一、前言
在windows服务的设计理念中,服务就是应该在后面默默无闻的跑,不要搞什么GUI之类的,但是凡事都有但是的时候,因为有些业务程序需要像服务程序一样的运行方式,也需要拥有GUI界面.然后,后面就有个session 0 隔离了,具体我也不多讲了,我也不懂.具体的百度吧哈哈哈.
二、上代码
-
无GUI创建进程
PROCESS_INFORMATION pi; //子进程句柄 DWORD returnCode; //子进程返回码 STARTUPINFO si = { sizeof(STARTUPINFO) }; BOOL CreateProcessNoService(const wchar_t * commandLine) { log_i(_T("创建进程中.....\n")); return CreateProcess(NULL, commandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); }
只要调用上面的函数就可以创建一个进程,如果不是作为服务调用创建的进程是可以创建带有GUI进程的,如果是服务调用的话就不能创建.
- 注意:涉及到字符串的都要使用宽字符
-
有GUI创建进程
PROCESS_INFORMATION pi; //子进程句柄 DWORD returnCode; //子进程返回码 STARTUPINFO si = { sizeof(STARTUPINFO) }; //--------------- HANDLE hToken; //用户token HANDLE hTokenDup; //用户token LPVOID pEnv; //服务环境下创建进程 BOOL CreateProcessForService(const wchar_t * commandLine) { log_i(_T("创建进程中.....\n")); DWORD dwSessionID = WTSGetActiveConsoleSessionId(); //获取当前处于活动状态用户的Token if (!WTSQueryUserToken(dwSessionID, &hToken)) { int nCode = GetLastError(); log_e(_T("获取用户token失败,错误码:%d\n"), nCode); CloseHandle(hToken); return FALSE; } //复制新的Token if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) { int nCode = GetLastError(); log_e(_T("复制用户token失败,错误码:%d\n"), nCode); CloseHandle(hToken); return FALSE; } //创建环境信息 if (!CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE)) { DWORD nCode = GetLastError(); log_e(_T("创建环境信息失败,错误码:%d\n"), nCode); CloseHandle(hTokenDup); CloseHandle(hToken); return FALSE; } ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = _T("winsta0\\default"); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); //开始创建进程 DWORD dwCreateFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT; if (!CreateProcessAsUser(hTokenDup, NULL, commandLine, NULL, NULL, FALSE, dwCreateFlag, pEnv, GetFullDir(), &si, &pi)) { DWORD nCode = GetLastError(); log_e(_T("创建进程失败,错误码:%d\n"), nCode); DestroyEnvironmentBlock(pEnv); CloseHandle(hTokenDup); CloseHandle(hToken); return FALSE; } //创建一个进程 return TRUE; }
- 注意:涉及到字符串的都要使用宽字符
三、总结
如果想知道怎么创建服务的朋友可以看我的另外的一篇博文创建windows服务.有什么疑问可以多多交流.