1. 程式人生 > >如何在Windows服務中以當前使用者啟動一個程式

如何在Windows服務中以當前使用者啟動一個程式


總所周知,大多數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);