TL; DR :
CreateProcess(?, ?, ?, ...)
用于:
%*
) 我有以下问题:
CreateProcess
所以,我想要做的是创build一个非常简单的可执行文件启动程序,这将是一个batch file的等价物:
set PATH=... set WHATEVER=... ...\3rd-pty-tool.exe -switch1 -switch2 %* exit /B %ERRORLEVEL%
我当然不想把任何bat2exe转换器的东西搞砸了 – 反正当我有Visual Studio的时候太难看了。
原则上 通过CreateProcess
运行另一个可执行文件是微不足道 的 :
STARTUPINFO info={sizeof(info)}; PROCESS_INFORMATION processInfo; if (CreateProcess(?, ?, ?, ?, ?, ?, ?, ?, &info, &processInfo)) { WaitForSingleObject(processInfo.hProcess, INFINITE); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); }
通过_putenv
等设置subprocess的环境。 也很容易。
但对我来说不是微不足道的是传递给CreateProcess
:
BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation );
%*
等价物? lpApplicationName
,只lpCommandLine
或两者? 不是一个愚蠢的: CreateProcess执行Windows命令
应该是合理的直截了当。
BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation );
让我们按顺序。
lpApplicationName
– 如果你有要运行的可执行文件的完整路径,把它放在这里。 这样可以确保获得所需的可执行文件,即使PATH上有另一个具有相同名称的可执行文件。
lpCommandLine
– 第一个元素是可执行文件的名称。 如果你已经指定了lpApplicationName
这个不需要完全限定,甚至是可执行文件的实际名称,但是它确实需要存在。 这必须是一个可写的缓冲区,它不能是一个常量字符串。
如果你的额外参数可以在命令行的末尾进行,这很简单:
wchar_t buffer[1024]; wcscpy_s(buffer, _countof(buffer), GetCommandLine()); wcscat_s(buffer, _countof(buffer), L" -switch1 -switch2");
否则,你需要解析命令行来找到插入参数的正确位置,如下所示:
while (*lpCmdLine == L' ') lpCmdLine++; while (ch = *lpCmdLine) { if (ch == L'"') for (lpCmdLine++; ch = *lpCmdLine; lpCmdLine++) if (ch == L'"') break; if (ch == L' ') break; lpCmdLine++; } while (*lpCmdLine == L' ') lpCmdLine++;
lpProcessAttributes
和lpThreadAttributes
– NULL
。
bInheritHandles
– TRUE
,因为您希望孩子继承标准手柄。
dwCreationFlags
– 在你的场景中不需要,所以0
。
lpEnvironment
– NULL
以传递当前环境。 在某些情况下,您希望显式构建一个新的环境或修改环境的副本,但是因为您的过程只是为了启动不必要的子项而存在。
lpCurrentDirectory
– 用于继承当前目录的NULL
。
lpStartupInfo
– 调用GetStartupInfo
来填充与当前进程相同的设置,或者将其保留为空,就像您发布的代码一样。
lpProcessInformation
– 这是一个输出参数,如代码中所示使用。 在你的场景中,如果一个应用程序正在为另一个应用程序站立,那么可能需要保留该流程句柄,并在退出之前使用它来等待子流程退出。 (如果您知道如果您在孩子之前退出,您的父母不会感到困惑,则不需要这样做。)
除了确保设置bInheritHandles
外,您不需要对标准句柄做任何特殊的操作。 默认是让孩子保持与父母相同的标准手柄。