为啥在 C++ 方法中使用 system("some.exe") 不像命令行那样工作?

Posted

技术标签:

【中文标题】为啥在 C++ 方法中使用 system("some.exe") 不像命令行那样工作?【英文标题】:Why does using system("some.exe") in C++ method not work like the command line?为什么在 C++ 方法中使用 system("some.exe") 不像命令行那样工作? 【发布时间】:2013-01-29 01:54:34 【问题描述】:

我正在为 Windows 编写一个程序,该程序最终必须启动位于同一台计算机上的不同的预先存在的 .exe。它将多个参数传递给这个 .exe 文件。我正在阅读实际的命令和参数并构建命令,但我也尝试用相同的结果对其进行硬编码。这是硬编码的版本(我是从一个使用相同.exe 的旧 C 程序中挑选出来的):

system("c://IQapture//dmon2_6_IHD -p2 c://IQapture//mon_table_101_Tx8.txt 11 0 0");

所以在原程序里面int _cdecl main(int argc, char**argv)这个使用系统是可行的。在我的 C++ 类方法中的 C++ 程序中,当我发出命令时,正确的程序会启动,但它会立即弹出一个错误对话框,指出发生了错误。我将用于启动 exe 的系统字符串回显到控制台。在它失败后,我复制并粘贴了与 echo'd 相同的行,这次 exe 运行没有错误。这是可重复的。如果与时间有关,我尝试在发出系统命令之前添加 10 秒延迟,但这没关系。加上原来的旧程序不需要延迟。这对我来说意味着字符串是正确的并且目标程序可以工作。不知何故,system() 调用与直接命令行调用不同。该程序编译并构建良好。我正在使用 Visual Studio 2010。

是否有人对如何使 system() 调用像命令行调用一样工作有想法?

【问题讨论】:

为什么所有这些正斜杠?另外,你确定你是从同一个目录运行命令吗? IIRC, system(x) 运行 cmd.exe /c x 所以试着把它放在命令行中。还要检查当前目录和环境变量是否相同,尤其是PATH。 这个例子是我从一个使用这个有效的 exe 的旧程序中复制和粘贴的。我不知道为什么它使用两个正斜杠,但它有效。我的程序中没有执行“cd”或任何类似更改目录的操作,因此我的 .exe 所在的目录应该是默认目录。 @Harry - 所以只需发出 system("pwd")、system("Path") 和 system("env")?我应该指出,具有所有必需硬件的目标系统不在这里。我只有在现场才能尝试,所以我提出了额外的问题,而不是仅仅尝试。 嗯,cdset 而不是 pwdenv,但基本上,是的。发出system("cmd.exe") 来启动命令shell,然后尝试从该shell 手动运行程序,并检查您是否在预期的目录中以及环境是否符合预期,这可能会更简单。 【参考方案1】:

这看起来真的不像 Windows 会喜欢的那种东西……试试用反斜杠代替:

system("c:\\IQapture\\dmon2_6_IHD -p2 c:\\IQapture\\mon_table_101_Tx8.txt 11 0 0");

如果这仍然不起作用,您很可能遇到以下问题之一:

您当前的工作目录有误; 缺少环境变量; 您的程序使用错误的用户权限运行; 您的程序占用了衍生进程所需的资源(例如您尚未关闭它需要作为输入的文件)。

【讨论】:

与正斜杠同样有效。你只需要一个,因为它不会像反弹一样逃脱 进入 Windows 是个坏习惯。许多 Windows 程序具有蹩脚的选项处理技能,将正斜杠(即使在字符串中间)解释为命令行选项。许多其他程序在解析路径名时会假设目录分隔符。因此,虽然cmd.exe 会愉快地运行使用 unix 风格的目录分隔符指定的程序,但使用它们不一定是个好主意。 @paddy - 后者的建议听起来不错。我将不得不做更多的探索,并更多地了解目标程序。谢谢。 是的,写出一个文件,然后启动另一个程序来处理它,但忘记事先关闭文件并不罕见。祝你好运。 客户进行了一项实验,当我的程序仍在运行时,我让他们打开第二个命令提示符并剪切并粘贴该行。它没有用。然后他们让我的程序退出并再次尝试,这次成功了。似乎是我没有释放资源的有力证据。现在,如果我能看到它是什么......【参考方案2】:

有很多事情需要考虑——环境、运行程序的用户、父进程以及继承的内容……看看CreateProcess函数的参数。您的系统调用的调用可能与命令行的调用不匹配(尽管这可能不是问题,更简单的事情更有可能。)

我建议在深入研究创建标志和安全属性等问题之前,从错误开始,排除简单的原因,如环境、当前目录等。

【讨论】:

【参考方案3】:

你的斜线是反的。试试:

system("c:/IQapture/dmon2_6_IHD -p2 c:/IQapture/mon_table_101_Tx8.txt 11 0 0");

您可以使用反斜杠\,但因为这是字符串中的转义序列起始符(对于 C/C++),这就是您连续使用两个的原因。因为编译器会将\\ 转换为字符串中的单个斜杠:

因此:

system("c:\\IQapture\\dmon2_6_IHD -p2 c:\\IQapture\\mon_table_101_Tx8.txt 11 0 0");

// Is equivelent to the command line string:

> c:\IQapture\dmon2_6_IHD -p2 c:\IQapture\mon_table_101_Tx8.txt 11 0 0

但是 Windows 支持这两种类型的斜线的时间比我记得的要长。所以下面的命令行是等价的。

> c:/IQapture/dmon2_6_IHD -p2 c:/IQapture/mon_table_101_Tx8.txt 11 0 0

在字符串中使用“/”(在 C/C++ 中)不需要转义。所以你只需要按原样使用它:

system("c:/IQapture/dmon2_6_IHD -p2 c:/IQapture/mon_table_101_Tx8.txt 11 0 0");

【讨论】:

两个命令行不一定等价;这取决于dmon2_6_IHD.exe 如何解析命令行。 有趣的是,每个人都关心斜线,尽管我特别提到我从已知有效的源代码中复制了该行。我仍然想知道为什么“错误”的斜杠会起作用,所以答案通常是有用的信息。 @Tod:那是因为// 被视为/./,相当于/

以上是关于为啥在 C++ 方法中使用 system("some.exe") 不像命令行那样工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥通过 system("color YX") 在 C++ 控制台应用程序中更改颜色不是最佳解决方案?

C++调用bat后,为啥运行完不出结果

已经安装好了gcc 但是为啥还出现Cannot find appropriate C++ compiler on this system

dubbo 服务启动之后自动退出,为啥?

为啥在 C++ 中没有强制内联的标准方法?

为啥我什至应该考虑在 C++ 中使用结构? [复制]