繁体   English   中英

CreateProcess和命令行参数

[英]CreateProcess and command line arguments

背景信息: Windows 7,Visual C ++ 2010 Express

问题: CreateProcess()通过'无效的命令行参数'继续返回

说明:我正在编写一段使用Windows API的CreateProcess调用外部程序的代码。 到目前为止,我已接到使用一个外部程序的电话:

if( !CreateProcess( "C:\\Temp\\convert.exe",
    t_str,        // Arguments
    ...
}
//where t_str is " C:\\img1.jpeg C:\\img1.pgm" (ImageMagick if you're wondering). 

即使我将所有数据都推送到Windows字符串和指针中,我也可以完美地工作。 所以我复制了CreateProcess()的所有修改,以便对另一个外部程序进行另一次调用:

 if( !CreateProcess( "C:\\Temp\\sift.exe",
     t_str2,        // Arguments
     ...
 }
 //where t_str2 is ` < C:\\img1.pgm > C:\\img1.key`

基本上,一些非常相似,但所有变量名称都已更改(因为我有两个调用运行串行)。 这就是问题所在; 这不会运行,而是打印出“无效的命令行参数:<C:\\ img1.pgm”。 当然,这个命令在命令提示符下工作正常,但在我的代码中没有。

我将t_str2切换到其他一些不太复杂的东西(因为我知道sift.exe如何工作),我得到了相同的结果。 当我只进行筛选而不是转换时,会发生同样的事情。

问题:可能导致此问题的原因是什么? 我该怎么做才能进一步调试这个问题? 关于我正在使用的方法的替代方案的任何建议? 任何帮助表示赞赏。 我可以提供进一步的代码,但它非常直接,并没有太多可能出错。

您不能直接使用命令行重定向运算符和CreateProcess() 您必须生成cmd.exe的实例并将操作符传递给它,例如:

CreateProcess( "C:\\windows\\system32\\cmd.exe", t_str2, ...))

其中t_str2"/CC:\\\\Temp\\\\sift.exe < C:\\\\img1.pgm > C:\\\\img1.key" 可以通过读取%COMSPEC%环境变量来确定cmd.exe的实际路径。

在第二个示例中,您尝试使用标准输入和重定向,这是命令行应用程序的符号。 但它们不是有效的程序参数。 如果你想使用重定向,你应该打开管道并手动读/写输入/输出文件。 在这里,您可以找到如何使用输入/输出重定向实现流程创建的示例。

CreateProcess有一些烦人的陷阱,如果你还没有引用官方文档,那么Stack Exchange中较旧的答案可能会使这个过程有点麻烦。

  1. CreateProcess参数1大部分是可选的,这对于第一个参数来说真的很奇怪。 如果您不想指定它,请使用NULL ,否则您应该阅读非特定 文档 ,了解如何在不将参数1设置为NULL时使用参数1。
  2. 如果将参数1设置为NULL ,则应用程序需要是参数2的第一部分。

再次感谢雷米清除我最初答案中的奇怪行为。


此代码示例仅需要Windows上的基本VC ++编译器,并且能够在桌面上创建和存储将由记事本打开的文件。

如果这不实用,请随意使用%temp%或其他位置放置测试文件。 该应用程序将一直运行,直到您关闭notepad.exe。 这也处理获取和返回退出代码。 如果您不希望它在退出之前无限期运行,则需要更新WaitForSingleObject行。

#include <Windows.h>

int main()
{
    STARTUPINFOA startup_info = { 0 };
    LPSTARTUPINFOA p_startup_info = &startup_info;
    PROCESS_INFORMATION proc_info = { 0 };
    LPPROCESS_INFORMATION p_proc_info = &proc_info;
    char command_line[] = 
      "C:\\Windows\\System32\\cmd.exe /C notepad.exe \"%USERPROFILE%\\Desktop\\test.txt\"";

    bool process_created = CreateProcess(
        NULL,
        command_line,
        NULL,
        NULL,
        FALSE,
        DETACHED_PROCESS,
        NULL,
        NULL,
        p_startup_info,
        p_proc_info
    );

    if (!process_created) { return -3; }

    DWORD process_exit;

    WaitForSingleObject(proc_info.hThread, INFINITE);

    GetExitCodeProcess(p_proc_info->hProcess, &process_exit);

    return (int)process_exit;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM