<p>Looking for an example that:</p>

<ol>
<li>Launches an EXE</li>
<li>Waits for the EXE to finish.</li>
<li>Properly closes all the handles when the executable finishes.</li>
</ol>

[{'answer_id': 42543, 'author': 'crashmstr', 'author_id': 1441, 'author_profile': 'https://Stackoverflow.com/users/1441', 'pm_score': 5, 'selected': False, 'text': '<p>There is an example at <a href="http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx" rel="noreferrer"><a href="http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx</a></a></p>\n\n<p>Just replace the <code>argv[1]</code> with your constant or variable containing the program.</p>\n\n<pre><code>#include &lt;windows.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;tchar.h&gt;\n\nvoid _tmain( int argc, TCHAR *argv[] )\n{\n    STARTUPINFO si;\n    PROCESS_INFORMATION pi;\n\n    ZeroMemory( &amp;si, sizeof(si) );\n    si.cb = sizeof(si);\n    ZeroMemory( &amp;pi, sizeof(pi) );\n\n    if( argc != 2 )\n    {\n        printf("Usage: %s [cmdline]\\n", argv[0]);\n        return;\n    }\n\n    // Start the child process. \n    if( !CreateProcess( NULL,   // No module name (use command line)\n        argv[1],        // Command line\n        NULL,           // Process handle not inheritable\n        NULL,           // Thread handle not inheritable\n        FALSE,          // Set handle inheritance to FALSE\n        0,              // No creation flags\n        NULL,           // Use parent\'s environment block\n        NULL,           // Use parent\'s starting directory \n        &amp;si,            // Pointer to STARTUPINFO structure\n        &amp;pi )           // Pointer to PROCESS_INFORMATION structure\n    ) \n    {\n        printf( "CreateProcess failed (%d).\\n", GetLastError() );\n        return;\n    }\n\n    // Wait until child process exits.\n    WaitForSingleObject( pi.hProcess, INFINITE );\n\n    // Close process and thread handles. \n    CloseHandle( pi.hProcess );\n    CloseHandle( pi.hThread );\n}\n</code></pre>\n'}, {'answer_id': 42544, 'author': '1800 INFORMATION', 'author_id': 3146, 'author_profile': 'https://Stackoverflow.com/users/3146', 'pm_score': 7, 'selected': True, 'text': '<p>Something like this:</p>\n\n<pre><code>STARTUPINFO info={sizeof(info)};\nPROCESS_INFORMATION processInfo;\nif (CreateProcess(path, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &amp;info, &amp;processInfo))\n{\n    WaitForSingleObject(processInfo.hProcess, INFINITE);\n    CloseHandle(processInfo.hProcess);\n    CloseHandle(processInfo.hThread);\n}\n</code></pre>\n'}, {'answer_id': 42583, 'author': 'Mike Ellery', 'author_id': 1362, 'author_profile': 'https://Stackoverflow.com/users/1362', 'pm_score': 3, 'selected': False, 'text': '<p>if your exe happens to be a console app, you might be interested in reading the stdout and stderr -- for that, I\'ll humbly refer you to this example:</p>\n\n<p><a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;q190351" rel="noreferrer">http://support.microsoft.com/default.aspx?scid=kb;EN-US;q190351</a></p>\n\n<p>It\'s a bit of a mouthful of code, but I\'ve used variations of this code to spawn and read.</p>\n'}, {'answer_id': 42729, 'author': 'Andy', 'author_id': 3857, 'author_profile': 'https://Stackoverflow.com/users/3857', 'pm_score': 3, 'selected': False, 'text': "<p>On a semi-related note, if you want to start a process that has more privileges than your current process (say, launching an admin app, which requires Administrator rights, from the main app running as a normal user), you can't do so using CreateProcess() on Vista since it won't trigger the UAC dialog (assuming it is enabled). The UAC dialog is triggered when using ShellExecute(), though.</p>\n"}, {'answer_id': 99645, 'author': 'jussij', 'author_id': 14738, 'author_profile': 'https://Stackoverflow.com/users/14738', 'pm_score': 4, 'selected': False, 'text': '<p>If you application is a Windows GUI application then using the code below to do the waiting is not ideal as messages for your application will not be getting processing. To the user it will look like your application has hung.</p>\n\n<pre><code>WaitForSingleObject(&amp;processInfo.hProcess, INFINITE)\n</code></pre>\n\n<p>Something like the <strong><em>untested</em></strong> code below might be better as it will keep processing the windows message queue and your application will remain responsive:</p>\n\n<pre><code>//-- wait for the process to finish\nwhile (true)\n{\n  //-- see if the task has terminated\n  DWORD dwExitCode = WaitForSingleObject(ProcessInfo.hProcess, 0);\n\n  if (   (dwExitCode == WAIT_FAILED   )\n      || (dwExitCode == WAIT_OBJECT_0 )\n      || (dwExitCode == WAIT_ABANDONED) )\n  {\n    DWORD dwExitCode;\n\n    //-- get the process exit code\n    GetExitCodeProcess(ProcessInfo.hProcess, &amp;dwExitCode);\n\n    //-- the task has ended so close the handle\n    CloseHandle(ProcessInfo.hThread);\n    CloseHandle(ProcessInfo.hProcess);\n\n    //-- save the exit code\n    lExitCode = dwExitCode;\n\n    return;\n  }\n  else\n  {\n    //-- see if there are any message that need to be processed\n    while (PeekMessage(&amp;message.msg, 0, 0, 0, PM_NOREMOVE))\n    {\n      if (message.msg.message == WM_QUIT)\n      {\n        return;\n      }\n\n      //-- process the message queue\n      if (GetMessage(&amp;message.msg, 0, 0, 0))\n      {\n        //-- process the message\n        TranslateMessage(&amp;pMessage-&gt;msg);\n        DispatchMessage(&amp;pMessage-&gt;msg);\n      }\n    }\n  }\n}\n</code></pre>\n'}, {'answer_id': 340042, 'author': 'Bob Moore', 'author_id': 9368, 'author_profile': 'https://Stackoverflow.com/users/9368', 'pm_score': 2, 'selected': False, 'text': "<p>Bear in mind that using <code>WaitForSingleObject</code> can get you into trouble in this scenario. The following is snipped from a tip on my website:</p>\n\n<blockquote>\n  <p>The problem arises because your application has a window but isn't pumping messages. If the spawned application invokes SendMessage with one of the broadcast targets (<em>HWND_BROADCAST</em> or <em>HWND_TOPMOST</em>), then the SendMessage won't return to the new application until all applications have handled the message - but your app can't handle the message because it isn't pumping messages.... so the new app locks up, so your wait never succeeds.... DEADLOCK.</p>\n</blockquote>\n\n<p>If you have absolute control over the spawned application, then there are measures you can take, such as using SendMessageTimeout rather than SendMessage (e.g. for DDE initiations, if anybody is still using that). But there are situations which cause implicit SendMessage broadcasts over which you have no control, such as using the SetSysColors API for instance.</p>\n\n<p>The only safe ways round this are:</p>\n\n<ol>\n<li>split off the Wait into a separate thread, or </li>\n<li>use a timeout on the Wait and use PeekMessage in your Wait loop to ensure that you pump messages, or </li>\n<li>use the <code>MsgWaitForMultipleObjects</code> API.</li>\n</ol>\n"}, {'answer_id': 5862370, 'author': 'pcunite', 'author_id': 645583, 'author_profile': 'https://Stackoverflow.com/users/645583', 'pm_score': 3, 'selected': False, 'text': '<p>Perhaps this is the most complete?\n<a href="http://goffconcepts.com/techarticles/createprocess.html" rel="nofollow noreferrer">http://goffconcepts.com/techarticles/createprocess.html</a></p>\n'}, {'answer_id': 46831649, 'author': 'Blue7', 'author_id': 3052832, 'author_profile': 'https://Stackoverflow.com/users/3052832', 'pm_score': 3, 'selected': False, 'text': '<p>Here is a new example that works on windows 10. When using the windows10 sdk you have to use CreateProcessW instead. This example is commented and hopefully self explanatory.</p>\n\n<pre><code>#ifdef _WIN32\n#include &lt;Windows.h&gt;\n#include &lt;iostream&gt;\n#include &lt;stdio.h&gt;\n#include &lt;tchar.h&gt;\n#include &lt;cstdlib&gt;\n#include &lt;string&gt;\n#include &lt;algorithm&gt;\n\nclass process\n{\npublic:\n\n    static PROCESS_INFORMATION launchProcess(std::string app, std::string arg)\n    {\n\n        // Prepare handles.\n        STARTUPINFO si;\n        PROCESS_INFORMATION pi; // The function returns this\n        ZeroMemory( &amp;si, sizeof(si) );\n        si.cb = sizeof(si);\n        ZeroMemory( &amp;pi, sizeof(pi) );\n\n        //Prepare CreateProcess args\n        std::wstring app_w(app.length(), L\' \'); // Make room for characters\n        std::copy(app.begin(), app.end(), app_w.begin()); // Copy string to wstring.\n\n        std::wstring arg_w(arg.length(), L\' \'); // Make room for characters\n        std::copy(arg.begin(), arg.end(), arg_w.begin()); // Copy string to wstring.\n\n        std::wstring input = app_w + L" " + arg_w;\n        wchar_t* arg_concat = const_cast&lt;wchar_t*&gt;( input.c_str() );\n        const wchar_t* app_const = app_w.c_str();\n\n        // Start the child process.\n        if( !CreateProcessW(\n            app_const,      // app path\n            arg_concat,     // Command line (needs to include app path as first argument. args seperated by whitepace)\n            NULL,           // Process handle not inheritable\n            NULL,           // Thread handle not inheritable\n            FALSE,          // Set handle inheritance to FALSE\n            0,              // No creation flags\n            NULL,           // Use parent\'s environment block\n            NULL,           // Use parent\'s starting directory\n            &amp;si,            // Pointer to STARTUPINFO structure\n            &amp;pi )           // Pointer to PROCESS_INFORMATION structure\n        )\n        {\n            printf( "CreateProcess failed (%d).\\n", GetLastError() );\n            throw std::exception("Could not create child process");\n        }\n        else\n        {\n            std::cout &lt;&lt; "[          ] Successfully launched child process" &lt;&lt; std::endl;\n        }\n\n        // Return process handle\n        return pi;\n    }\n\n    static bool checkIfProcessIsActive(PROCESS_INFORMATION pi)\n    {\n        // Check if handle is closed\n            if ( pi.hProcess == NULL )\n            {\n                printf( "Process handle is closed or invalid (%d).\\n", GetLastError());\n                return FALSE;\n            }\n\n        // If handle open, check if process is active\n        DWORD lpExitCode = 0;\n        if( GetExitCodeProcess(pi.hProcess, &amp;lpExitCode) == 0)\n        {\n            printf( "Cannot return exit code (%d).\\n", GetLastError() );\n            throw std::exception("Cannot return exit code");\n        }\n        else\n        {\n            if (lpExitCode == STILL_ACTIVE)\n            {\n                return TRUE;\n            }\n            else\n            {\n                return FALSE;\n            }\n        }\n    }\n\n    static bool stopProcess( PROCESS_INFORMATION &amp;pi)\n    {\n        // Check if handle is invalid or has allready been closed\n            if ( pi.hProcess == NULL )\n            {\n                printf( "Process handle invalid. Possibly allready been closed (%d).\\n");\n                return 0;\n            }\n\n        // Terminate Process\n            if( !TerminateProcess(pi.hProcess,1))\n            {\n                printf( "ExitProcess failed (%d).\\n", GetLastError() );\n                return 0;\n            }\n\n        // Wait until child process exits.\n            if( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_FAILED)\n            {\n                printf( "Wait for exit process failed(%d).\\n", GetLastError() );\n                return 0;\n            }\n\n        // Close process and thread handles.\n            if( !CloseHandle( pi.hProcess ))\n            {\n                printf( "Cannot close process handle(%d).\\n", GetLastError() );\n                return 0;\n            }\n            else\n            {\n                pi.hProcess = NULL;\n            }\n\n            if( !CloseHandle( pi.hThread ))\n            {\n                printf( "Cannot close thread handle (%d).\\n", GetLastError() );\n                return 0;\n            }\n            else\n            {\n                 pi.hProcess = NULL;\n            }\n            return 1;\n    }\n};//class process\n#endif //win32\n</code></pre>\n'}, {'answer_id': 70626460, 'author': 'reem_mikulsky', 'author_id': 15799356, 'author_profile': 'https://Stackoverflow.com/users/15799356', 'pm_score': 0, 'selected': False, 'text': '<p>Here is a solution for <code>CreateProcessA</code></p>\n<pre><code>STARTUPINFOW initInfo = { 0 };\ninitInfo.cb = sizeof(initInfo);\nPROCESS_INFORMATION procInfo = { 0 };\n\nCreateProcessA(PATH_FOR_EXE, NULL, NULL, NULL, FALSE, 0, NULL, NULL, (LPSTARTUPINFOA)&amp;initInfo, &amp;procInfo);\n</code></pre>\n'}, {'answer_id': 71851383, 'author': 'Giver Khadka', 'author_id': 10586192, 'author_profile': 'https://Stackoverflow.com/users/10586192', 'pm_score': 0, 'selected': False, 'text': '<pre><code>#include &lt;Windows.h&gt;\nvoid my_cmd()\n{\n    STARTUPINFO si;\n    PROCESS_INFORMATION pi;\n    ZeroMemory(&amp;si, sizeof(si));\n    si.cb = sizeof(si);\n    ZeroMemory(&amp;pi, sizeof(pi));\n    // CMD command here\n    char arg[] = &quot;cmd.exe /c E:/Softwares/program.exe&quot;;\n    // Convert char string to required LPWSTR string\n    wchar_t text[500];\n    mbstowcs(text, arg, strlen(arg) + 1);\n    LPWSTR command = text;\n    // Run process\n    CreateProcess (NULL, command, NULL, NULL, 0, \n    CREATE_NO_WINDOW, NULL, NULL, &amp;si, &amp;pi);\n}\n</code></pre>\n<p>This works fine for me. No popup windows and cmd command runs as expected. Just needed to convert the CHAR pointer into WCHAR pointer and add extra &quot;cmd.exe /c&quot; before every command.</p>\n'}]
['https://Stackoverflow.com/questions/42531', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/814/']