在服务中启动带有界面的程序

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家拍砖

 

 参考文章:http://blog.csdn.net/goingup/article/details/2932752#reply

 

在服务中启动带有界面的程序。

一、函数定义

1、窄字节版本
#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;
} 
2、宽字节版本
/**
 * @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的。所以运行出错了。

这里只是编译器把它优化了。

你可能感兴趣的:(虚拟机/云计算/服务)