如何在c ++中调用:: CreateProcess来启动Windows可执行文件?

c++ windows winapi

115764 观看

8回复

14109 作者的声誉

寻找一个例子:

  1. 启动EXE
  2. 等待EXE完成。
  3. 在可执行文件完成时正确关闭所有句柄。
作者: jm. 的来源 发布者: 2008 年 9 月 3 日

回应 8


18

24027 作者的声誉

有一个例子 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 );
}
作者: crashmstr 发布者: 2008 年 9 月 3 日

65

100006 作者的声誉

决定

像这样的东西:

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);
}
作者: 1800 INFORMATION 发布者: 2008 年 9 月 3 日

7

1482 作者的声誉

如果您的exe恰好是一个控制台应用程序,您可能有兴趣阅读stdout和stderr - 为此,我会谦虚地向您推荐此示例:

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

这是一些代码,但我已经使用此代码的变体来生成和读取。

作者: Mike Ellery 发布者: 2008 年 9 月 3 日

7

25207 作者的声誉

在半相关说明中,如果您要启动一个具有比当前进程更多权限的进程(例如,从以普通用户身份运行的主应用程序启动需要管理员权限的管理应用程序),则不能在Vista上使用CreateProcess()执行此操作,因为它不会触发UAC对话框(假设它已启用)。但是,使用ShellExecute()时会触发UAC对话框。

作者: Andy 发布者: 2008 年 9 月 3 日

9

9252 作者的声誉

如果您的应用程序是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);
      }
    }
  }
}
作者: jussij 发布者: 2008 年 9 月 19 日

3

5682 作者的声誉

请记住,WaitForSingleObject在这种情况下使用可能会让您陷入困境。以下内容摘自我网站上的提示:

出现问题的原因是您的应用程序有一个窗口但没有抽取消息。如果生成的应用程序使用其中一个广播目标(HWND_BROADCASTHWND_TOPMOST)调用SendMessage ,则SendMessage将不会返回到新应用程序,直到所有应用程序都处理了该消息 - 但您的应用程序无法处理该消息,因为它不是' t泵消息....所以新的应用程序锁定,所以你的等待永远不会成功.... DEADLOCK。

如果您对生成的应用程序具有绝对控制权,那么您可以采取一些措施,例如使用SendMessageTimeout而不是SendMessage(例如,对于DDE启动,如果有人仍在使用它)。但是有些情况会导致您无法控制的隐式SendMessage广播,例如使用SetSysColors API。

唯一安全的方法是:

  1. 将Wait分成一个单独的线程,或者
  2. 在Wait上使用超时并在Wait循环中使用PeekMessage以确保您输出消息,或者
  3. 使用MsgWaitForMultipleObjectsAPI。
作者: Bob Moore 发布者: 2008 年 12 月 4 日

5

966 作者的声誉

也许这是最完整的? http://goffconcepts.com/techarticles/development/cpp/createprocess.html

作者: pcunite 发布者: 2011 年 5 月 2 日

3

527 作者的声誉

这是一个适用于Windows 10的新示例。使用windows10 sdk时,您必须使用CreateProcessW。这个例子被评论并希望自我解释。

#ifdef _WIN32
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <cstdlib>
#include <string>
#include <algorithm>

class process
{
public:

    static PROCESS_INFORMATION launchProcess(std::string app, std::string arg)
    {

        // Prepare handles.
        STARTUPINFO si;
        PROCESS_INFORMATION pi; // The function returns this
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );

        //Prepare CreateProcess args
        std::wstring app_w(app.length(), L' '); // Make room for characters
        std::copy(app.begin(), app.end(), app_w.begin()); // Copy string to wstring.

        std::wstring arg_w(arg.length(), L' '); // Make room for characters
        std::copy(arg.begin(), arg.end(), arg_w.begin()); // Copy string to wstring.

        std::wstring input = app_w + L" " + arg_w;
        wchar_t* arg_concat = const_cast<wchar_t*>( input.c_str() );
        const wchar_t* app_const = app_w.c_str();

        // Start the child process.
        if( !CreateProcessW(
            app_const,      // app path
            arg_concat,     // Command line (needs to include app path as first argument. args seperated by whitepace)
            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() );
            throw std::exception("Could not create child process");
        }
        else
        {
            std::cout << "[          ] Successfully launched child process" << std::endl;
        }

        // Return process handle
        return pi;
    }

    static bool checkIfProcessIsActive(PROCESS_INFORMATION pi)
    {
        // Check if handle is closed
            if ( pi.hProcess == NULL )
            {
                printf( "Process handle is closed or invalid (%d).\n", GetLastError());
                return FALSE;
            }

        // If handle open, check if process is active
        DWORD lpExitCode = 0;
        if( GetExitCodeProcess(pi.hProcess, &lpExitCode) == 0)
        {
            printf( "Cannot return exit code (%d).\n", GetLastError() );
            throw std::exception("Cannot return exit code");
        }
        else
        {
            if (lpExitCode == STILL_ACTIVE)
            {
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        }
    }

    static bool stopProcess( PROCESS_INFORMATION &pi)
    {
        // Check if handle is invalid or has allready been closed
            if ( pi.hProcess == NULL )
            {
                printf( "Process handle invalid. Possibly allready been closed (%d).\n");
                return 0;
            }

        // Terminate Process
            if( !TerminateProcess(pi.hProcess,1))
            {
                printf( "ExitProcess failed (%d).\n", GetLastError() );
                return 0;
            }

        // Wait until child process exits.
            if( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_FAILED)
            {
                printf( "Wait for exit process failed(%d).\n", GetLastError() );
                return 0;
            }

        // Close process and thread handles.
            if( !CloseHandle( pi.hProcess ))
            {
                printf( "Cannot close process handle(%d).\n", GetLastError() );
                return 0;
            }
            else
            {
                pi.hProcess = NULL;
            }

            if( !CloseHandle( pi.hThread ))
            {
                printf( "Cannot close thread handle (%d).\n", GetLastError() );
                return 0;
            }
            else
            {
                 pi.hProcess = NULL;
            }
            return 1;
    }
};//class process
#endif //win32
作者: Blue7 发布者: 2017 年 10 月 19 日
32x32