如何在C/C++中使用Windows下包含空格的路径名调用popen()?

Gab*_*leV 6 c c++ popen quoting

我试图用这样的mingw调用popen():

#define RUN_COMMAND "\"C:\\Program Files\\CA\\BrightStor ARCserve Backup\\ca_qmgr.exe\" \"-list\""
int main() {
    outputPointer = popen(RUN_COMMAND, "r");
    ...
}
Run Code Online (Sandbox Code Playgroud)

但我无法让它发挥作用.我认为这是一个引用噩梦...

小智 7

这个解决方案的灵感来自Kaz的回复

事实证明,popen函数剥离了整个事物的引号,例如."C:/Program Files"C:/Program Files"Ab cd.exe" "ef gh"ab cd" "ef gh.你可以通过在整个事物周围添加引号来解决这个问题,例如.""ab cd.exe" "ef gh""这变得"ab cd.exe" "ef gh"如预期的那样.


Kaz*_*Kaz 5

这个问题原来是可以解决的。(不过,与 Windows 中的大多数内容一样,不是 100%)。

popen函数打开一个系统命令,这意味着它几乎可以肯定只是将字符串参数插入到cmd.exe /c <here>.

cmd.exe /cWindows 命令提示符下进行一些交互式实验后,我们找到了一种运行路径名中包含空格的程序的方法。

带引号的天真尝试,不:

C:\>cmd /c "foo bar"
'foo' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)

我们可以用扬抑符转​​义引号吗?

C:\>cmd /c ^"foo bar^"
'foo' is not recognized [...]
Run Code Online (Sandbox Code Playgroud)

空间怎么样?

C:\>cmd /c foo^ bar
'foo' is not recognized [...]
Run Code Online (Sandbox Code Playgroud)

只引用空格怎么样?

C:\>cmd /c foo" "bar
'foo" "bar' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)

啊哈!这是有希望的!它实际上是在尝试运行foo bar吗?让我们来看看:

C:\>copy con "foo bar.bat"
echo i am foo bar
^Z
        1 file(s) copied.

C:\>cmd /c foo" "bar

C:\>echo i am foo bar
i am foo bar
Run Code Online (Sandbox Code Playgroud)

啊哈!运行了名称中带有空格的批处理文件!

因此,现在我正在 Visual Studio 2008 中尝试以下操作:

#include <stdio.h>

int main()
{
    FILE *in = _popen("C:\\Program\" \"Files\\Internet\" \"Explorer\\iexplore.exe", "r");

    if (in) {
        char line[200];
        printf("successfully opened!\n");
        if (fgets(line, 200, in))
            fputs(line, stdout);
        _pclose(in);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它可以很好地启动 Internet Explorer,然后在fgets您退出浏览器之前阻止它(并且由于没有输出而无法读取任何内容)。

它适用于使用 Microsoft C 运行时库的 MinGW;事实上,我想出了这个解决方案来修复使用 MinGW 移植到 Windows 的编程语言库中的错误。

注意事项:

这种转义技巧不会转义前导空格。它似乎确实适用于尾随空格。两者都不是问题;我们不经常看到以空格开头或结尾的路径名,更不用说可执行路径名了。

我也找不到一种方法来转义可能作为路径一部分出现的嵌入双引号,同时处理空格。人们在创建类似C:\Program Files\Bob's so-called "editor"\bedit.exe.


hlo*_*dal -1

根据 popen 的手册页:

命令参数是一个指向包含 shell 命令行的以 null 结尾的字符串的指针。该命令使用 -c 标志传递到 /bin/sh ;解释(如果有)由 shell 执行。

所以你想要的是转义字符串以sh进行解析。您不需要转义-list参数,并且可以尝试转义空格而不是引用整个程序名称。我这里没有 Windows 系统可供测试,但我建议

#define RUN_COMMAND "C:\\Program Files\\CA\\BrightStor\\ ARCserve\\ Backup\\ca_qmgr.exe -list"
int main() {
    outputPointer = popen(RUN_COMMAND, "r");
    ...
}
Run Code Online (Sandbox Code Playgroud)