c++ CreateProcess() 不适用于带有正斜杠“/”的应用程序和参数。 - 与 App=NULL 一起使用
解决方案:“
ShellAndWait(NULL, _FinalShellStrCmd, "WAIT", 240, 1);
使用 stringstream 将 App 和 Arg 组合到 _FinalShellStrCmd 中,将第一个 arg 保留为 NULL。无论是使用正斜杠还是反斜杠,它都可以正常工作。再次感谢大家。
我正在使用 boost 来获取当前路径,然后我得到“d:/bin/test. 现在,我尝试使用 CreateProcess() 库函数调用下面的 ShellAndWait() 。在目录路径中使用反斜杠“\”,例如.. d:\bin\test。它的工作方式就像魅力。
我将应用程序路径和参数打印到dos提示符下,然后将它们复制并粘贴到dos提示符下,它执行正常。例如,D:/bin/test/test.exe d:/bin/test/test.dat app-path args
如果我将 app-path 和 args 放入下面的 ShellWandWait 函数中,它什么也没做。我怀疑 CreateProcess() 不会采用带有正斜杠“/”的路径或目录。 有人给我一些灯吗?再次感谢。
int BasicExcelCell::ShellAndWait(char *AppName, char *AppArgument, char *Wait, DWORD TimeOut=0, DWORD IgnoreErrorFlag=0)
{
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
TimeOut = TimeOut * 1000;
if (Wait == "NOWAIT")
ShellExecute(NULL,"open",AppName, AppArgument," ", SW_SHOW );
else //WAIT
{
//printf("ShellExecute WAIT\n");
printf("Appname:%s AppArgs:%s\n", AppName, AppArgument);
UINT olderrormode;
if (IgnoreErrorFlag)
{
olderrormode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX);
}
if (CreateProcess(AppName, AppArgument,
NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
std::cout<<"WaitingSingleOjbec"<<endl;
DWORD dwret = WaitForSingleObject(ProcessInfo.hProcess,TimeOut);
switch (dwret)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
default:
TerminateProcess(ProcessInfo.hProcess,0);
break;
}
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
if (IgnoreErrorFlag)
{
SetErrorMode(olderrormode);
}
}
return 0;
}
Solution:"
ShellAndWait(NULL, _FinalShellStrCmd, "WAIT", 240, 1);
Using stringstream to combine App and Arg into _FinalShellStrCmd, leave first arg as NULL. It worked fine with either forward or back slashes. Thanks all again.
I am using boost to get current path, then I get "d:/bin/test.
Now, I try to call ShellAndWait() below with CreateProcess() library function. With backslash "\ in the directory path eg.. d:\bin\test. it works like charm.
I had printout the app path and args to dos prompt, then I copy them and past to the dos prompt, it executed OK. Example, D:/bin/test/test.exe d:/bin/test/test.dat
app-path args
if I put the app-path and args to ShellWandWait function below, and it did nothing. I am suspected that the CreateProcess() would not take path or directory with forward slash "/".
Anyone give me some lights here? Thanks again.
int BasicExcelCell::ShellAndWait(char *AppName, char *AppArgument, char *Wait, DWORD TimeOut=0, DWORD IgnoreErrorFlag=0)
{
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
TimeOut = TimeOut * 1000;
if (Wait == "NOWAIT")
ShellExecute(NULL,"open",AppName, AppArgument," ", SW_SHOW );
else //WAIT
{
//printf("ShellExecute WAIT\n");
printf("Appname:%s AppArgs:%s\n", AppName, AppArgument);
UINT olderrormode;
if (IgnoreErrorFlag)
{
olderrormode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX);
}
if (CreateProcess(AppName, AppArgument,
NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
std::cout<<"WaitingSingleOjbec"<<endl;
DWORD dwret = WaitForSingleObject(ProcessInfo.hProcess,TimeOut);
switch (dwret)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
default:
TerminateProcess(ProcessInfo.hProcess,0);
break;
}
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
if (IgnoreErrorFlag)
{
SetErrorMode(olderrormode);
}
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您已经有了答案:CreateProcess 不适用于正斜杠。修复斜杠 =>该代码有效。某些面向用户的 API 和接口比其他 API 和接口更容易被接受
You already have the answer: CreateProcess doesn't work with forward-slashes. Fix the slashes => the code works. Certain user-facing APIs and interfaces are more accepting than others
CreateProcess 不能使用正斜杠是有充分理由的:Windows 程序经常将它们用作命令行选项说明符(如“dir /w”或“format c: /q”)。 DOS 的一个旧包袱规定,正斜杠参数不需要用空格分隔 - 因此 DOS/Windows 控制台命令的以下格式也是有效的:“dir/w”、“format c:/q” ”。
我猜想 Windows API 程序员希望 CreateProcess 支持这一点,因此他们决定不将正斜杠解析为路径分隔符。与 DOS 和现有 Windows 程序的兼容性比与 POSIX 的兼容性更重要。
There's a good reason CreateProcess won't work with forward slashes: Windows programs often use them as a command line option specifier (like "dir /w" or "format c: /q"). An old baggage from DOS dictates that that forward-slash-arguments don't need to be separated by a space - so the following format for DOS/Windows console command is also valid: "dir/w", "format c:/q".
I guess the windows API programmers wanted CreateProcess to support this, so they decided not to parse forward slashes as path separators. Compatibility with DOS and existing Windows programs was more important than compatibility with POSIX.
我认为最好的方法是创建一个 boost:filesystem::path 对象,然后使用 make_preferred() 。让 boost 库处理字符替换工作。
I think the best way is to create a
boost:filesystem::path
object and then usemake_preferred()
. Let boost library handle the character replace job.