从 Win32 启动 .exe 文件

Launch an .exe file from Win32

我一直在尝试从 Win32 应用程序启动一个 exe 文件,但是我无法让它工作。我也想向它传递一个论点,但我认为我做的不正确。以前在这里问过类似的问题,但似乎他们想要 运行 一个命令(cmd.exe),而不是启动另一个 exe 文件。具体来说,我想启动 Java appletviewer。

我目前的代码是这样的:

LPCWSTR pszViewerPath = L"C:\Path\to\appletviewer.exe"; // I know that this path is correct
PWSTR pszFilePath;
// get the path to the HTML file to pass to appletviewer.exe, store it in pszFilePath...

STARTUPINFO si;
PROCESS_INFORMATION pi;

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

CreateProcess(pszViewerPath,
   pszFilePath,
   NULL,
   NULL,
   FALSE,
   0,
   NULL,
   NULL,
   &si,
   &pi);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

我遇到的问题是命令提示符 window 短暂出现,然后消失得无影无踪。

我做错了什么?我原本打算使用 ShellExcecute 但读到它效率低下。

我该如何解决这个问题?感谢您的帮助。

当同时使用CreateProcess()lpApplicationNamelpCommandLine参数时,习惯上将应用程序文件路径重复作为第一个命令行参数。这甚至在 CreateProcess() documentation:

If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to by lpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

试试像这样的东西:

LPCWSTR pszViewerPath = L"C:\Path\to\appletviewer.exe"; // I know that this path is correct

PWSTR pszFilePath;
// get the path to the HTML file to pass to appletviewer.exe, store it in pszFilePath...

PWSTR pszCmdLine = (PWSTR) malloc((lstrlen(pszViewerPath) + lstrlen(pszFilePath) + 6) * sizeof(WCHAR));
if (!pszCmdLine)
{
    // error handling...
}
else
{
    wsprintf(pszCmdLine, L"\"%s\" \"%s\"", pszViewerPath, pszFilePath);

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

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

    if (!CreateProcess(
        pszViewerPath,
        pszCmdLine,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi))
    {
        // error handling...
    }
    else
    {
        // optional: wait for the process to terminate...
        WaitForSingleObject(pi.hProcess, INFINITE);

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }

    free(pszCmdLine);
}

在这种情况下,根本没有必要使用 lpApplicationName 参数:

If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin

CreateProcess(NULL, pszCmdLine, ...)