使用参数列表中的绝对路径启动QProcess

时间:2014-03-14 13:36:14

标签: c++ windows qt qprocess

问题

我正在尝试使用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"

任何人都可以向我解释我是如何实现这一目标的吗?

3 个答案:

答案 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\"
");