2

アプリには 2 つのプロセスがあります。1. Windows サービスである「myService.exe」。2. 「myService.exe」と同じディレクトリにある「myApp.exe」。

このプロセスは、CreateProcessAsUser API を使用して「myService.exe」によって生成されます。現在のユーザーの vpn プロファイルにアクセスする必要があるため、(システム コールを使用して) プロセスを直接開始する代わりに、この API を使用する必要があります。

「myApp.exe」のパスをハードコーディングすると、正常に動作し、プロセスが作成されますが、「myService.exe」の現在のディレクトリを取得して取得した同じパスはプロセスを作成せず、エラーコード 2 (ファイルが見つかりません) を返します。 .

私は Visual Studio 2008 を使用しています。プロジェクトは ASCII モードでコンパイルされており、以下のコードでは Unicode ではありません。Unicode api を使用してみました (最後に「A」はありません)。それもうまくいきませんでした。

問題は、現在のパスを取得することではありません。パスが System32 フォルダーではないことが確認されています。

    HANDLE hToken;
LPSTR exePath = GetCommandLineA();
string exePathStr = exePath;
char fileExeChar[256];
strcpy(fileExeChar,exePathStr.c_str());
string serverExe = "myService.exe";
for(unsigned int i=0;i<exePathStr.length()-(serverExe.length() + 1);i++)
{
    fileLocation += fileExeChar[i];// removing the service.exe from the path

}
LPSTR fileLocationLp = const_cast<LPSTR>(fileLocation.c_str());

LPCSTR progName = (LPCSTR)"myapp.exe";

char errStr[100];
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
int k = WTSQueryUserToken (WTSGetActiveConsoleSessionId (), &hToken);
ZeroMemory( &si, sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = (LPSTR)"winsta0\\default";
    ZeroMemory( &pi,sizeof(pi));
if ( !CreateProcessAsUserA(
                      hToken,
                      progName,
                      fileLocationLp,  
                      NULL,
                      NULL,
                      FALSE,
                      dwCreationFlag,
                      NULL,
                      NULL,
                      &si,
                      &pi
          ) )
{
    sprintf(errStr, "CreateProcessAsUser Failed %d\n", GetLastError());
} 
else
{
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(hToken);
}
4

1 に答える 1

5

デフォルトでは、Windows サービスはSystem32ディレクトリで実行されます。これが、絶対パスが指定されていない場合、他の実行可能ファイルを見つけることができない理由です。GetCurrentDirectory()これは、Windows サービスからを取得することで確認できます。

これを解決するには (Windows サービスと他の実行可能ファイルが同じディレクトリにあると仮定します):

  • を使用して Windows サービス実行可能ファイルのフル パスを取得し、最初の引数としてGetModuleFileName()渡します。NULL
  • フルパスからディレクトリを抽出します
  • 次に、他の実行可能ファイルへのパスを作成し、それを Windows サービスに渡すか、CreateProcessAsUser()または使用して Windows サービスのディレクトリを変更します。SetCurrentDirectory()
于 2012-07-03T09:59:02.313 に答える