问题
我正在尝试使用QProcess启动应用程序,但我无法弄清楚如何提供带有空格的参数。我试过了
我尝试了什么
QString appPath = "\"C:/Users/USER/Google Drive/projects/qt_projects/someproject/
ghostpdl-8.71-win32/gxps-871.exe\"";
QStringList arguments;
arguments << "-sDEVICE=pdfwrite" << "-sOutputFile=\"C:/Users/USER/Google Drive/
projects/qt_projects/someproject/output.pdf\"" << "-dNOPAUSE \"C:/Users/USER/
Google Drive/projects/qt_projects/someproject/file.xps\"";
QProcess *converter = new QProcess();
converter->start(appPath, arguments);
我认为这与运行控制台命令(工作原理)相同:
"C:/Users/USER/Google Drive/projects/qt_projects/someproject/
ghostpdl-8.71-win32/gxps-871.exe" -sDEVICE=pdfwrite
-sOutputFile="C:/Users/USER/Google Drive/projects/qt_projects/
someproject/output.pdf" -dNOPAUSE "C:/Users/USER/Google Drive/
projects/qt_projects/someproject/file.xps"
任何人都可以向我解释我是如何实现这一目标的吗?
答案 0 :(得分:1)
理解的关键是:在Windows上通常没有“多个命令行参数”这样的东西。命令行作为单个字符串传递给接收应用程序。在Unices上,命令行作为多个参数传递,因此它更加稳固。
本讨论的其余部分是关于Windows的。
将命令行拆分为字符串取决于您将参数传递给的应用程序的C运行时库。此行为不标准化。您需要参考相关C运行时的文档来弄清楚它是如何实现的。是的,这很糟糕。
有些程序无法用Qt打开吗?
完全没有。您需要知道的是,在开始该过程之前,Qt正在使用空格分隔符加入参数列表。如果参数包含空格且不以 '"'
开头或结尾,则它将包含在'"'
中。如果参数包含 '"'
,则会对其进行转义。这是在qprocess_win.cpp, qt_create_commandline()
中完成的。这样做是为了与MSVC运行时兼容。应用程序当然可能更喜欢以自己的方式执行操作,例如,根本不使用msvcrt。
答案 1 :(得分:0)
这里的问题是你通过将参数拆分为参数列表来分离参数。你可以这样做,但你只需要一个单个参数传递给命令,该命令封装在引号中。
所以,让我们拿控制台命令: -
"gxps-871.exe" -sDEVICE=pdfwrite -sOutputFile="C:/Users/USER/Google Drive/projects/qt_projects/someproject/output.pdf" -dNOPAUSE "C:/Users/USER/Google Drive/projects/qt_projects/someproject/file.xps"
为了便于阅读,我删除了命令的路径。
参数需要被视为传递给命令的一个参数
所以我们可以创建一个参数字符串,但是我们要创建一个参数,所以添加引号......
QString arg("\"<args to go here>\"");
现在我们添加参数,这些参数在引号内添加以创建单个参数,但是转义所有其他引号以保持空白区域...
QString arg("\"-sDEVICE=pdfwrite -sOutputFile=\"C:/Users/USER/Google Drive/projects/qt_projects/someproject/output.pdf\" -dNOPAUSE \"C:/Users/USER/Google Drive/projects/qt_projects/someproject/file.xps\"\"");
然后设置appPath ...
QString appPath = "\"C:/Users/USER/Google Drive/projects/qt_projects/someproject/ghostpdl-8.71-win32/gxps-871.exe\"";
将参数添加到QStringList ..
QStringList arguments;
arguments << arg;
开始这个过程...
converter->start(appPath, arguments);
这里的参数列表是相当不必要的,你可以在一行中完成所有这些: -
converter->start("\"C:/Users/USER/Google Drive/projects/qt_projects/someproject/ghostpdl-8.71-win32/gxps-871.exe\" \"-sDEVICE=pdfwrite -sOutputFile=\"C:/Users/USER/Google Drive/projects/qt_projects/someproject/output.pdf\" -dNOPAUSE \"C:/Users/USER/Google Drive/projects/qt_projects/someproject/file.xps\"\"");
但很容易错过报价,或报价的逃避而且它变得相当混乱,你不觉得吗?!
答案 2 :(得分:0)
根据这个this blog post QProcess,内部调用createProcess。如果尝试启动需要提升的可执行文件,则对非提升进程的createProcess调用将失败,并显示ERROR_ELEVATION_REQUIRED。
在博客文章中,他通过调用shellexecute来解决问题,但是我也无法做到这一点。我的最终解决方案是使用windows.h中的system()函数。使用system(),您可以执行与cmd.exe相同的命令。用法示例:
#include <windows.h>
...
system(""C:\\test_folder\\ghostpdl-8.71-win32\\gxps-871.exe -sDEVICE=pdfwrite -
sOutputFile=\"C:\\test_folder\\output.pdf\" -dNOPAUSE \"C:\\test_folder\\file.xps\"
");