转载请标明是引用于 http://blog.csdn.net/chenyujing1234
欢迎大家拍砖
参考文章:http://blog.csdn.net/goingup/article/details/2932752#reply
在服务中启动带有界面的程序。
#include
#include
#include
#include
//根据进程名称得到进程token
BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName)
{
if(!lpName)
{
return FALSE;
}
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE,pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS,&hToken);
CloseHandle (hProcessSnap);
return (bRet);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = TRUE;
}
else
bRet = FALSE;
CloseHandle (hProcessSnap);
return (bRet);
}
BOOL RunProcess(LPCTSTR lpImage)
{
HANDLE hToken;
STARTUPINFO si;
PROCESS_INFORMATION pi;
char strExe[256] = "explorer.exe";
if(!lpImage)
{
return FALSE;
}
if(!GetTokenByName(hToken, strExe))
{
return FALSE;
}
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop =_T("winsta0//default");
BOOL bResult = CreateProcessAsUser(hToken,lpImage,NULL,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
CloseHandle(hToken);
if(bResult)
{
OutputDebugString(_T("CreateProcessAsUser ok!/r/n"));
}
else
{
OutputDebugString(_T("CreateProcessAsUser false!/r/n"));
}
return bResult;
}
/**
* @brief 根据进程名称得到进程token
*
* @param[out] hToken 获得进程token
* @param[in] lpName 要查找的exe名称
*
* @return TRUE 成功
* FALSE 失败
* @note
*/
BOOL GetTokenByName(HANDLE &hToken, LPWSTR lpName)
{
if(!lpName)
{
return FALSE;
}
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
if(!wcscmp(_wcsupr(pe32.szExeFile),_wcsupr(lpName)))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE,pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS,&hToken);
CloseHandle (hProcessSnap);
return (bRet);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = TRUE;
}
else
bRet = FALSE;
CloseHandle (hProcessSnap);
return bRet;
}
/**
* @brief 得到当前登陆用户名
*
* @param[out] lpBuffer 获得的用户名
* @param[in] pcbBuffer 指定要获得的用户名字符串的长度
*
* @return TRUE 成功
* FALSE 失败
* @note
*/
BOOL GetCurrentUserName(LPWSTR lpBuffer, LPDWORD pcbBuffer)
{
HANDLE hToken = NULL;
wchar_t strExe[256] = L"explorer.exe";
DWORD cbti = 0;
PTOKEN_USER ptiUser = NULL;
SID_NAME_USE snu;
// 得到shell的token
if(!GetTokenByName(hToken, strExe))
{
return FALSE;
}
// 取得所需空间大小
if (GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti))
{
CloseHandle(hToken);
return FALSE;
}
// 分配空间
ptiUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbti);
if(!ptiUser)
{
CloseHandle(hToken);
return FALSE;
}
// 取得token信息
if (!GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
{
CloseHandle(hToken);
HeapFree(GetProcessHeap(), 0, ptiUser);
return FALSE;
}
WCHAR szDomain[256];
DWORD nDomain = 256;
// 根据用户的sid得到用户名和domain
if (FALSE == LookupAccountSid(NULL,
ptiUser->User.Sid,
lpBuffer,
pcbBuffer,
szDomain,
&nDomain,
&snu))
{
CloseHandle(hToken);
HeapFree(GetProcessHeap(), 0, ptiUser);
return FALSE;
}
CloseHandle(hToken);
HeapFree(GetProcessHeap(), 0, ptiUser);
return TRUE;
}
在BOOL RunProcess(LPCTSTR lpImage)函数中如果是:
那么运行时会报以下的错:
原因:
这是因为GetTokenByName时传进来的是const类型的字符串,而_strupr中的参数要求不是const的。所以运行出错了。
这里只是编译器把它优化了。