0

Windows サービスから GUI アプリケーションを起動しようとしています。しかし、CreateEnvironmentBlock() 関数を呼び出すと、しばらくハングした後、「SampleService.exe が動作を停止し、閉じられました。問題が発生したため、アプリケーションが正常に動作しなくなりました。解決策がある場合は、ウィンドウが通知します。 " 以下は私のコードです。

DWORD dwSessionId = 0;          // Session ID
HANDLE hToken = NULL;           // Active session token
HANDLE hDupToken = NULL;        // Duplicate session token
WCHAR szErr[1024] = {0};
STARTUPINFO* startupInfo;
PROCESS_INFORMATION processInformation;
PWTS_SESSION_INFO pSessionInfo = 0;
DWORD dwCount = 0;

LPVOID lpEnvironment = NULL;            // Environtment block

OutputDebugString(_T("My Sample Service: startApplication: Entry"));

// Get the list of all terminal sessions 

WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);

int dataSize = sizeof(WTS_SESSION_INFO);

// look over obtained list in search of the active session

for (DWORD i = 0; i < dwCount; ++i)
{
   WTS_SESSION_INFO si = pSessionInfo[i];
   if (WTSActive == si.State)
   { 
      // If the current session is active – store its ID
      dwSessionId = si.SessionId;
      break;
   }
}   

OutputDebugString(_T("My Sample Service: startApplication: freewtsmemory"));
WTSFreeMemory(pSessionInfo);

OutputDebugString(_T("My Sample Service: startApplication: WTSQueryUserToken"));
// Get token of the logged in user by the active session ID 
BOOL bRet = WTSQueryUserToken(dwSessionId, &hToken);

if (!bRet)
{       
  swprintf(szErr, _T("WTSQueryUserToken Error: %d"), GetLastError());
  OutputDebugString(szErr);
  return false;
}

OutputDebugString(_T("My Sample Service: startApplication: duplicatetokenex"));

// Get duplicate token from the active logged in user's token
bRet = DuplicateTokenEx(hToken,     // Active session token
             TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,           // Desired access
                     NULL,                      // Token attributes                                         
                     SecurityImpersonation,    // Impersonation level
                     TokenPrimary,              // Token type
                     &hDupToken);               // New/Duplicate token
if (!bRet)
{
    swprintf(szErr, _T("DuplicateTokenEx Error: %d"), GetLastError());
OutputDebugString(szErr);
    return false;
}

// Get all necessary environment variables of logged in user
// to pass them to the process

OutputDebugString(_T("My Sample Service: startApplication: createenvironmentblock"));

try{
 bRet = CreateEnvironmentBlock(&lpEnvironment, hDupToken, FALSE);

}
catch( const exception &e) 
{
swprintf(szErr, _T("CreateEnvironmentBlock Exception: %s"), e);
OutputDebugString(szErr);
    return false;
}
if(!bRet)
{
    swprintf(szErr, _T("CreateEnvironmentBlock Error: %d"), GetLastError());
OutputDebugString(szErr);
    return false;
}


// Initialize Startup and Process info  
startupInfo->cb = sizeof(STARTUPINFO);

OutputDebugString(_T("My Sample Service: startApplication: createprocess"));

// Start the process on behalf of the current user 

BOOL returnCode = CreateProcessAsUser(hDupToken, 
                            NULL, 
                            L"C:\\KM\\TEST.exe", 
                            NULL,
                            NULL,
                            FALSE,
                            NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE |      CREATE_UNICODE_ENVIRONMENT,
                            lpEnvironment,
                            NULL,
                            startupInfo,
                            &processInformation);
if( !returnCode)
{
    swprintf(szErr, _T("CreateProcessAsUser Error: %d"), GetLastError());
    OutputDebugString(szErr);
    return false;
}

CloseHandle(hDupToken);
return true;

debugview に「My Sample Service: startApplication: createenvironmentblock」と表示され、サービスが停止しました。この問題に関して私を助けてください。Windows Vistaを使用していることに注意してください。

よろしく、KM。

4

1 に答える 1

1

ポインターを定義済みの方法で使用する前に、ポインターを初期化する必要があります。

STARTUPINFO* startupInfo;

...

startupInfo->cb = sizeof(STARTUPINFO);

変数が使用されている場所の近くで変数が宣言されていれば、この間違いはより明白である可能性があります。変数は関数の先頭でのみ宣言できるという規則に従う場合は、さらに関数を作成することを検討してください。

そして、価値のあることとして、この種の問題をトラブルシューティングするときは、Visual Studio のデバッガーをサービス プロセスにアタッチすることができますOutputDebugString。サービス プロセスが Visual Studio によってビルドされる最後のプロセスであることを確認してください。プロセス、シンボル ファイル、およびソース コードはすべて調整する必要があります。

于 2013-09-08T00:38:15.103 に答える