QT中QProcess调用命令行的痛苦经历

阅读目录

在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类提供的成员函数,其使用的具体代码如下:


1

2

3

4

QProcess p(0);

p.start(command,args); //command是要执行的命令,args是参数

p.waitForFinished();//等待完成

qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

QProcess p(0);

QString command = "E:/test_rar_course/rar.exe";

QStringList args;

args.append("a");

args.append("-k");

args.append("-r");

args.append("-s");

args.append("-m1");

args.append("E:/test_rar_course/test.rar");

args.append("E:/test_rar_course/direct1/");

args.append("E:/test_rar_course/direct2/");

args.append("E:/test_rar_course/test.txt");

p.execute(command,args);//command是要执行的命令,args是参数

p.waitForFinished();

qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

QProcess p(0);

p.setWorkingDirectory("E:/test_rar_course/");//指定进程的工作目录

QString command = "E:/test_rar_course/rar.exe";

QStringList args;

args.append("a");

args.append("-k");

args.append("-r");

args.append("-s");

args.append("-m1");

args.append("-wE:/test_rar_course/");//指定rar.exe的工作目录

args.append("test.rar");

args.append("direct1/");

args.append("direct2/");

args.append("test.txt");

p.execute(command,args);//command是要执行的命令,args是参数

p.waitForFinished();

qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());//获取输出

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


1

2

3

4

5

6

QProcess p(0);

p.setWorkingDirectory("E:/test_rar_course/");//指定进程的工作目录

QString command = "E:/test_rar_course/test.bat";

p.start(command);

p.waitForFinished();

qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());

而test.bat的内容为如下:


1

2

cd /d E:/test_rar_course/

E:/test_rar_course/rar.exe a -k -r -s -m1 -wE:/test_rar_course/ test.rar direct1/ direct2/ test.txt

我直接在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执行也有问题:


1

2

3

4

5

void SystemTool::GenerateIndexRar(char * command)

{

    if(command == NULL) return ;

    system(command);

}

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


1

2

3

4

5

6

7

8

9

10

#include <windows.h>

void SystemTool::GenerateIndexRar(char * command)

{

         if(command == NULL) return ;

         /**

            WinExec 的windows 调用,可以通过参数SW_HIDE隐藏命令行黑窗口

            并且命令的路径是可以带括号的

          */

         WinExec(command,SW_HIDE);

}

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

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

http://www.cnblogs.com/wangqiguo/p/4609228.html

时间: 2024-10-05 23:47:56

QT中QProcess调用命令行的痛苦经历的相关文章

QT中QProcess调用详解及实验

在QT程序中需要将某目录和文件压缩为一个rar的压缩包,于是想到了在QT中通过QProcess类调用命令行的rar.exe来达到效果,但是没想到QProcess类用起来很麻烦,而且达不到效果,折腾了2天仍然没找到原因,使用另外一种办法解决了. 创建压缩包的方法 在windows平台创建压缩包,可以直接使用rar.exe,该程序在安装winrar之后,在其安装目录下就可以找到.该程序是winrar对应的命令行版本,其语法例子如下: rar.exe a -k -r -s -m1 test.rar d

Linux下QT中执行shell命令

当需要在QT中执行shell命令时可以利用以下方法: (1)首先包含头文件: #include <QProcess> (2)执行shell命令: QProcess::execute("ls"); ///////////////////// #include  <QProcess> void Widget:on_pushButton_clicked() { //* system("ls");//调用LINUX C函数库中的system(cons

system调用命令行命令而不显示命令行窗口

system调用命令行命令而不显示命令行窗口 通常用system调用命令行命令时都会弹出黑底白字的命令行窗口,下面的代码可以不显示弹出的命令行窗口. 代码如下 1 #pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" ) // 设置入口地址 2 #include <windows.h> 3 #include <stdio.h>

VC 6.0和CodeBlocks中如何设置命令行参数

VC 6.0 可以在IDE中设置好命令行参数,然后再运行.做法如下: 选择project下拉菜单的settings... 出现如下窗口,选中右边的debug标签,然后在Program arguments中填入相关命令行参数(注意argv[0]不需要填),点OK按钮确认. 然后运行就可以了. CodeBlocks 选择Project菜单下的Set program's arguments..., 如图 在Program arguments 文本框敲入相应的参数即可,argv[0]不需要填, 然后点击

QT uic rcc moc 命令行使用

QT uic rcc moc 命令行使用 PS C:\Users\lsgx> uic.exe --help Usage: C:\Qt\Qt5.5.1\5.5\msvc2012\bin\uic.exe [options] [uifile] Qt User Interface Compiler version 5.5.1 Options: -?, -h, --help Displays this help. -v, --version Displays version information. -d

Linux中mysql进入命令行报错:MYSQL ERROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;192.168.99.192&#39; (111)

场景:在Linux中安装mysql01和mysql02,通过VIP虚出一个VIP=192.168.99.192,mysql01为主ip为192.168.99.153,mysql02为备机ip为192.168.99.154 此时VIP在mysql01上通过 mysql01上连接VIP :mysql -h 192.168.99.192 -P 3306   结果是可以正常进入mysql命令行: 通过mysql02上远程连接VIP 会在界面上报错:mysql error 2003(HY000):Can'

python中调用命令行命令

http://blog.csdn.net/pipisorry/article/details/46972171 在Python/wxPython环境下,执行外部命令或者说在Python程序中启动另一个程序的方法 1.os.system(command) os.system()函数用来运行shell命令.此命令可以方便的调用或执行其他脚本和命令 #打开指定的文件 >>>os.system('notepad *.txt') 2.wx.Execute(command, syn=wx.EXEC_

TFS Release 步骤调用命令行返回失败信息的处理方法

TFS Release中自定义步骤时,可以选择"命令行",官方的文档中,并没有描述调用相关的程序后,如何返回失败信息.通过下面步骤,可以实现本标题描述的功能. 步骤一:编写Console Application. 说明:1.Main函数的返回值要设为int类型.-1代表程序执行失败. 2.Console负责向控制台输出信息,这些信息可以最终打印到Release的日志中. 3.不要throw exception,否则BuildAgent会挂起的. 步骤二:定义Release中的命令行命令

C# 调用命令行,参数有空格

在程序中调用cmd命令打开一个文件,而文件路径带有空格,如果直接把路径传给cmd,那么cmd就会把路径空格前面的部分当做是一个参数,空格后当做另一个参数,命令行执行把后边截掉了,导致程序出错,会弹出了C:\Program 不是内部或外部命令,也不是可运行的程序或批处理文件的错误提示.解决方法是把传入的参数前后添加双引号,如下: private static void ResxToRes(ArrayList ResxPath) { //ResxFile 是一个文件夹,用来存放 需要转换的.resx