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

Start QProcess with absolute paths in argument list

本文关键字:路径 启动 QProcess 参数 列表      更新时间:2023-10-16

问题

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

有人能向我解释一下我是怎么做到的吗?

理解的关键是:在Windows上通常没有"多个命令行参数"这回事。命令行作为单个字符串传递给接收应用程序。在Unices上,命令行是作为多个参数传递的,所以它在那里更理智。

本讨论的其余部分是关于Windows的。

将命令行拆分为字符串取决于您将参数传递到的应用程序的C运行库。这种行为是而非标准化的。您需要参考相关C运行库的文档来了解它是如何做到这一点的。是的,有那么糟糕。

是否有一些程序无法用Qt打开?

一点也不。您需要知道的是,在开始该过程之前,Qt使用空格分隔符连接参数列表。如果参数包含空格,且既不以'"'开头也不以含'"',则对其进行转义。这在qprocess_win.cpp, qt_create_commandline()中完成。这样做是为了与MSVC运行时兼容。当然,应用程序可能更喜欢用自己的方式做事,例如,根本不使用msvcrt。

这里的问题是通过将参数拆分为一个参数列表来分离参数。您可以这样做,但只需要一个参数就可以传递给命令,该命令封装在引号中。

因此,让我们使用控制台命令:-

"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""");

但很容易错过一句名言,或者一句名言的脱口而出,这会变得相当混乱,你不认为吗?!

根据这篇博客文章,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"
");