问题描述
我一直在尝试从 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,FALSE,&si,&pi);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
我遇到的问题是命令提示符窗口短暂出现,然后消失得无影无踪。
我做错了什么?我原本打算使用 ShellExcecute
,但读到它效率低下。
我该如何解决这个问题?感谢您的帮助。
解决方法
当同时使用 lpApplicationName
的 lpCommandLine
和 CreateProcess()
参数时,习惯上重复应用程序文件路径作为第一个命令行参数。这甚至在 CreateProcess()
documentation 中有说明:
如果lpApplicationName
和lpCommandLine
都为非NULL,则lpApplicationName
指向的空终止字符串指定要执行的模块,lpCommandLine
指向的空终止字符串指定要执行的模块{1}} 指定命令行。新进程可以使用 GetCommandLine
来检索整个命令行。 用 C 编写的控制台进程可以使用 argc
和 argv
参数来解析命令行。由于 argv[0]
是模块名称,C 程序员通常在命令行中重复模块名称作为第一个标记。
尝试更像这样的事情:
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,FALSE,&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
参数:
如果 lpApplicationName 为 NULL,则命令行的第一个以空格分隔的标记指定模块名称。如果您使用包含空格的长文件名,请使用带引号的字符串来指示文件名的结束位置和参数的开始位置
CreateProcess(NULL,...)