如何在Windows服務中以當前使用者啟動一個程式
阿新 • • 發佈:2019-02-05
總所周知,大多數Windows服務是以SYSTEM使用者啟動的,並且沒有任何互動介面的。SYSTEM使用者是系統中許可權最高的使用者,所以服務程式有極高的許可權,可以操作登錄檔,系統目錄等等。
但是有寫東西不一定許可權高就能取到,比如說想知道當前登入使用者的一些相關資訊,必須是當前使用者啟動的程式才可能得到這些資訊,用SYSTEM使用者啟動的服務反而得不到這些資訊,於是就有了需要在Windows服務中以當前使用者啟動一個程序的需求。
以下程式碼可以實現用當前使用者啟動一個程式,在Win7 64位機器上測試通過。
//獲取當前活動的SessionId DWORD dwSessionId = WTSGetActiveConsoleSessionId(); HANDLE hToken = NULL; HANDLE hTokenDup = NULL; LPVOID pEnv = NULL; STARTUPINFO si; PROCESS_INFORMATION pi; //獲取使用者Token if(!WTSQueryUserToken(dwSessionId, &hToken)) { CloseHandle(hToken); return; } //複製Token if(!DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hTokenDup)) { CloseHandle(hToken); return; } //獲取環境資訊 if(!CreateEnvironmentBlock(&pEnv,hTokenDup,FALSE)) { CloseHandle(hToken); CloseHandle(hTokenDup); return; } //設定啟動引數資訊 ZeroMemory( &si, sizeof( STARTUPINFO ) ); si.cb = sizeof( STARTUPINFO ); si.lpDesktop = "winsta0\\default"; ZeroMemory( &pi, sizeof(pi) ); DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS|CREATE_UNICODE_ENVIRONMENT|CREATE_NEW_CONSOLE; //以當前使用者啟動記事本 if(!CreateProcessAsUser(hTokenDup,"notepad.exe",NULL,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi)) { DestroyEnvironmentBlock(pEnv); CloseHandle(hTokenDup); CloseHandle(hToken); fOut.close(); } //等待啟動的程序結束 WaitForSingleObject(pi.hProcess, INFINITE); //清理工作 DestroyEnvironmentBlock(pEnv); CloseHandle(hTokenDup); CloseHandle(hToken);