使用`createProcess()`

时间:2015-06-22 17:36:41

标签: c++ windows batch-file

我正试图从我正在编写的一些C ++代码中提取Webots,但遇到了一些问题。我正在运行的Webots版本是7.4.3(由于某些无关的原因,我当时无法更新到8.1.0),这在解释命令行参数(https://www.cyberbotics.com/forum?message=5222)时有一个已知错误。

我想将特定文件作为参数传递,以便Webots打开它。它是Windows中用于处理此类文件的默认应用程序,因此,如果我只是在命令行上放置文件的路径,或者只是单击它,它将由Webots打开。我正在使用createProcess()从我的C ++程序调用webots,但是,将路径放在文件而不是程序可执行文件中会抛出错误(正如预期的那样,因为该文件不是可执行文件)。

奇怪的是,使用“运行”窗口(而不是cmd.exe),我可以按照假设(http://www.cyberbotics.com/dvd/common/doc/webots/guide/section2.2.html)传递参数。

应该注意的是,Webots安装提供webots.exewebots.bat,我假设在Windows中包含额外的库路径,因为如果我试图“丢失[...]。dll”运行webots.exe

所以我对这个问题有两个问题:

1)“运行”窗口与命令行之间究竟有什么区别,因为它们在调用相同命令时会显示不同的行为?

2)是否可以使用createProcess()调用“运行”窗口并发送命令作为参数运行?

编辑:

我正在编译的代码的相关片段:

//[...]
LPTSTR cmdArgs="C:\\path\\to\\file":
STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;

if(CreateProcess("C:\\Program Files (x86)\\Webots\\webots.bat", cmdArgs, 
    NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,
    NULL,&StartupInfo,&ProcessInfo))
{ 
    WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
} else {
    printf("Unable to execute");
}
//[...]

这样,Webots会打开但不会打开cmdArgs文件,如果我在调用时将Unable to execute作为第一个参数(cmdArgs作为第二个参数),我会得到NULL createProcess() - 我不知道的具体错误,必须更改代码以捕获它。

编辑2:

Webots.bat:

@echo off
setlocal
set Path=%CD%\lib;%CD%\mingw\bin;%CD%\msys\bin;%Path%
start webots.exe

1 个答案:

答案 0 :(得分:0)

这就是我的想法。这是CreateProcess official doc

试试这个:

LPTSTR cmdArgs = TEXT("/c \"C:\\Program Files (x86)\\Webots\\webots.bat\" \"C:\\path\\to\\file\"");
// The other statements
if(CreateProcess(TEXT("cmd.exe"), cmdArgs, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL,
 NULL, &info, &processInfo))
// The rest of the statements

做了什么:

  1. 根据上面的链接,lpCommandLine字符串中的第一个标记是程序(app)名称。就像在main中一样,argc[0]是可执行文件名。运行.bat文件时例外(这正是我们的情况);然后lpApplicationName应设置为cmd.exelpCommandLine设置为/c,后跟批次名称(和args)。
  2. 根据相同的文档,如果路径名称包含空格(在您的情况下,它们都包含空格),则必须将它们括在" s中。
  3. 我认为粘贴代码时会出现拼写错误,否则无法编译。 CreateProcess的最后两个参数不正确(我将&StratupInfo替换为&info&ProcessInfo替换为&processInfo)。
  4. 我做的最后一件事是将TEXT宏包含在程序中的任何文字字符串。编写适用于 ASCII WideChar 字符串的程序时,这是必需的。虽然它没有对您的代码产生任何可见差异,因为您没有定义UNICODE_UNICODE宏,这意味着您的程序使用 ASCII strings(嗯,我想知道为什么这是因为默认情况下 Visual Studio 定义它们;除非你手动定义它们),但如果你定义(或更好:un-undefine)它们,你会得到一堆乍看之下毫无意义的编译错误。