57

次の例を探しています。

  1. EXE を起動します
  2. EXE が終了するのを待ちます。
  3. 実行可能ファイルの終了時に、すべてのハンドルを適切に閉じます。
4

9 に答える 9

82

このようなもの:

STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
if (CreateProcess(path, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
    WaitForSingleObject(processInfo.hProcess, INFINITE);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
}
于 2008-09-03T20:45:53.117 に答える
24

に例がありますhttp://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx

argv[1]をプログラムを含む定数または変数に置き換えるだけです。

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

void _tmain( int argc, TCHAR *argv[] )
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    if( argc != 2 )
    {
        printf("Usage: %s [cmdline]\n", argv[0]);
        return;
    }

    // Start the child process. 
    if( !CreateProcess( NULL,   // No module name (use command line)
        argv[1],        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return;
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}
于 2008-09-03T20:45:11.917 に答える
12

アプリケーションが Windows GUI アプリケーションである場合、アプリケーションのメッセージが処理されないため、以下のコードを使用して待機を行うことは理想的ではありません。ユーザーには、アプリケーションがハングしたように見えます。

WaitForSingleObject(&processInfo.hProcess, INFINITE)

以下のテストされていないコードのようなものは、Windows メッセージ キューを処理し続け、アプリケーションの応答性が維持されるため、より良いかもしれません。

//-- wait for the process to finish
while (true)
{
  //-- see if the task has terminated
  DWORD dwExitCode = WaitForSingleObject(ProcessInfo.hProcess, 0);

  if (   (dwExitCode == WAIT_FAILED   )
      || (dwExitCode == WAIT_OBJECT_0 )
      || (dwExitCode == WAIT_ABANDONED) )
  {
    DWORD dwExitCode;

    //-- get the process exit code
    GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);

    //-- the task has ended so close the handle
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);

    //-- save the exit code
    lExitCode = dwExitCode;

    return;
  }
  else
  {
    //-- see if there are any message that need to be processed
    while (PeekMessage(&message.msg, 0, 0, 0, PM_NOREMOVE))
    {
      if (message.msg.message == WM_QUIT)
      {
        return;
      }

      //-- process the message queue
      if (GetMessage(&message.msg, 0, 0, 0))
      {
        //-- process the message
        TranslateMessage(&pMessage->msg);
        DispatchMessage(&pMessage->msg);
      }
    }
  }
}
于 2008-09-19T04:30:10.020 に答える
8

exeがコンソールアプリである場合は、stdoutとstderrを読むことに興味があるかもしれません。そのために、この例を謙虚に紹介します。

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q190351

少し一口のコードですが、私はこのコードのバリエーションを使用してスポーンして読み取りました。

于 2008-09-03T21:02:11.517 に答える
7

半関連のメモとして、現在のプロセスよりも多くの権限を持つプロセスを開始したい場合 (たとえば、通常のユーザーとして実行されているメイン アプリから、管理者権限が必要な管理アプリを起動する場合)、できません。これは、Vista で CreateProcess() を使用して行います。これは、UAC ダイアログをトリガーしないためです (有効になっていると仮定します)。ただし、ShellExecute() を使用すると、UAC ダイアログがトリガーされます。

于 2008-09-03T22:13:45.853 に答える
5

これが一番完成度が高いのではないでしょうか? http://goffconcepts.com/techarticles/createprocess.html

于 2011-05-02T20:55:40.807 に答える
4

WaitForSingleObjectこのシナリオでは、を使用すると問題が発生する可能性があることに注意してください。以下は私のウェブサイトのヒントから抜粋したものです。

この問題は、アプリケーションにウィンドウがありますが、メッセージをポンピングしていないために発生します。生成されたアプリケーションがブロードキャストターゲットの1つ(HWND_BROADCASTまたはHWND_TOPMOST)でSendMessageを呼び出す場合、SendMessageは、すべてのアプリケーションがメッセージを処理するまで新しいアプリケーションに戻りませんが、アプリはメッセージを処理できないため、メッセージを処理できません。 tメッセージをポンピングする....新しいアプリがロックされるため、待機が成功することはありません....デッドロック。

生成されたアプリケーションを完全に制御できる場合は、SendMessageではなくSendMessageTimeoutを使用するなどの対策があります(たとえば、DDEの開始の場合、誰かがまだそれを使用している場合)。ただし、たとえばSetSysColors APIを使用するなど、制御できない暗黙のSendMessageブロードキャストが発生する状況があります。

これを回避する唯一の安全な方法は次のとおりです。

  1. 待機を別のスレッドに分割する、または
  2. Waitでタイムアウトを使用し、WaitループでPeekMessageを使用して、メッセージを確実に送信するか、または
  3. MsgWaitForMultipleObjectsAPIを使用します。
于 2008-12-04T09:38:26.500 に答える