qt执行命令行失败_QT中QProcess调用命令行的痛苦经历(调用Winrar,设置工作目录,获得输出,注意引号与括号,等等)...

在QT项目中,作者尝试使用QProcess调用WinRAR命令行rar.exe创建压缩包,遇到工作目录设置、路径包含括号及引号转义等问题。通过创建批处理文件并修改批处理内容,以及调用C++ DLL中的system函数避免弹窗,最终成功解决问题。
摘要由CSDN通过智能技术生成

在QT程序中需要将某些目录和文件压缩为一个rar的压缩包,于是想到了在QT中通过QProcess类调用命令行的rar.exe来达到效果,但是没想到QProcess类用起来很麻烦,而且达不到效果,折腾了2天仍然没找到原因,使用另外一种办法解决了。

创建压缩包的方法

在windows平台创建压缩包,可以直接使用rar.exe,该程序在安装winrar之后,在其安装目录下就可以找到。该程序是winrar对应的命令行版本,其语法例子如下:

rar.exe a -k -r -s -m1 test.rar direct1/   direct2/  test.txt

例子对应的目录结构如下:

上面的命令表示在当前目录下创建压缩包 test.rar ,将当前目录下的 direct1目录以及其所有子目录和文件、direct2目录以及其子目录和文件、当前目录下的文件test.txt 都添加到test.rar压缩包中。

其中参数a表示添加到压缩包

参数-r表示递归添加

命令的问题解决了之后,那么下面就是如何在QT中调用该命令,实际上在QT中调用该命令就出现了很多问题。

在QT中调用命令行

QT中调用外部命令一般使用QProcess类提供的成员函数,其使用的具体代码如下:

套用上面的代码得到如下:

可以生成test.rar但是,该压缩包中将路径E:/test_rar_course也压缩进去了,而我需要的是打开压缩包之后仅仅看到direct1,direct2,test.txt3个项目,那么是不是设置一下工作目录就可以了呢:

我不仅添加-w参数(该参数为rar.exe的命令行参数,用于指定工作目录)为rar.exe命令指定工作目录,同时利用p.setWorkingDirectory()为启动的进程指定工作目录,运行之后报错,说找不到文件,我猜可能还是工作目录的问题,但是不知道问题在哪里,查了很多资料都无济于事,最终还是放弃了这种尝试,改成了下面的尝试:

而test.bat的内容为如下:

我直接在bat中通过cd命令切换工作目录,然后进行压缩,其中为了避免出现压缩绝对路径的情况,direct1,direct2,test.txt使用的都是相对路径,直接鼠标双击该test.bat运行OK,放在QT中运行OK,似乎完美的解决了问题。

但是我发现,如果目录中出现()括号字符就不行了,当有括号字符的时候在QProcess执行的报错中显示路径被括号截断,此后我把路径用引号引起来没效果:

"\"E:/test_rar_course(xx)/test.bat\""

根据网上搜索到的信息,用^符号对括号进行转义没有截断的报错了,但是命令执行还是没有效果,控制台也没有报错:

"E:/test_rar_course^(xx^)/test.bat"

到这里我不知道该怎么样去达到我的效果,唯一的感觉QProcess怎么这么难用,如果有知道的QT大神,烦请告诉一下。我想到用另外一种方式来实现,就是用C++写一个dll实现,然后QT中调用。

在QT中调用C++创建的dll

主要代码如下,实际上就是调用system函数,但是如果路径中有圆括号,还是需要用^符号进行转义,否则system执行也有问题:

但是除了圆括号要转义以外,还存在一个很不舒服的问题,就是每次执行都会弹出cmd的黑窗口,执行完成之后,窗口消失,代码改成下面的就好了:

到此完美解决该问题,既不需要对圆括号进行转义,同时也隐藏了黑窗口了。当然前述的test.bat的内容要在程序中动态生成,利用合适的路径替换掉test.bat中的路径。

最后调用如:SystemTool::GenerateIndexRar("E:/test_rar_course(xx)/test.bat");

Qt,你可以使用`QProcess`类来执行外部可执行程序并将其集成到对话框(Dialog)。下面是一个简单的示例代码片段,展示了如何创建一个对话框并在其启动一个外部程序: ```cpp #include <QApplication> #include <QDialog> #include <QPushButton> #include <QProcess> class MyDialog : public QDialog { public: explicit MyDialog(QWidget *parent = nullptr) : QDialog(parent) { // 创建一个按钮,点击后会执行外部程序 QPushButton *executeButton = new QPushButton("执行", this); connect(executeButton, &QPushButton::clicked, this, &MyDialog::onExecute); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(executeButton); setLayout(layout); } private slots: void onExecute() { // 使用QProcess开始一个新的进程,这里假设你想执行的是一个命令行工具"example_app.exe" QProcess process; QString executablePath = "path_to_your_example_app.exe"; // 替换为你实际的路径 process.start(executablePath); // 等待外部程序结束,可以设置timeout来处理超时情况 if (process.waitForFinished(-1)) { qDebug() << "外部程序执行完毕"; } else { qWarning() << "外部程序执行失败"; } } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建并显示对话框 MyDialog dialog; dialog.show(); return app.exec(); } ``` 在这个例子,当你点击对话框里的"执行"按钮,`onExecute`槽函数会被调用,然后`QProcess`会启动指定的外部应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值