溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

QT中QProcess調(diào)用詳解及實驗

發(fā)布時間:2020-07-23 14:46:18 來源:網(wǎng)絡 閱讀:1549 作者:WZM3558862 欄目:開發(fā)技術

在QT程序中需要將某目錄和文件壓縮為一個rar的壓縮包,于是想到了在QT中通過QProcess類調(diào)用命令行的rar.exe來達到效果,但是沒想到QProcess類用起來很麻煩,而且達不到效果,折騰了2天仍然沒找到原因,使用另外一種辦法解決了。

創(chuàng)建壓縮包的方法

在windows平臺創(chuàng)建壓縮包,可以直接使用rar.exe,該程序在安裝winrar之后,在其安裝目錄下就可以找到。該程序是winrar對應的命令行版本,其語法例子如下:

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

例子對應的目錄結構如下:

上面的命令表示在當前目錄下創(chuàng)建壓縮包 test.rar ,將當前目錄下的 direct1目錄以及其所有子目錄和文件、direct2目錄以及其子目錄和文件、當前目錄下的文件test.txt 都添加到test.rar壓縮包中。

其中參數(shù)a表示添加到壓縮包

參數(shù)-r表示遞歸添加

命令的問題解決了之后,那么下面就是如何在QT中調(diào)用該命令,實際上在QT中調(diào)用該命令就出現(xiàn)了很多問題。

在QT中調(diào)用命令行

QT中調(diào)用外部命令一般使用QProcess類提供的成員函數(shù),其使用的具體代碼如下:

1

2

3

4

QProcess p(0);

p.start(command,args); //command是要執(zhí)行的命令,args是參數(shù)

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

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

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


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是要執(zhí)行的命令,args是參數(shù)

p.waitForFinished();

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

可以生成test.rar但是,該壓縮包中將路徑E:/test_rar_course也壓縮進去了,而我需要的是打開壓縮包之后僅僅看到direct1,direct2,test.txt3個項目,那么是不是設置一下工作目錄就可以了呢:


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是要執(zhí)行的命令,args是參數(shù)

p.waitForFinished();

qDebug()<<QString::fromLocal8Bit(p.readAllStandardError());//獲取輸出

我不僅添加-w參數(shù)(該參數(shù)為rar.exe的命令行參數(shù),用于指定工作目錄)為rar.exe命令指定工作目錄,同時利用p.setWorkingDirectory()為啟動的進程指定工作目錄,運行之后報錯,說找不到文件,我猜可能還是工作目錄的問題,但是不知道問題在哪里,查了很多資料都無濟于事,最終還是放棄了這種嘗試,改成了下面的嘗試:


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的內(nèi)容為如下:

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命令切換工作目錄,然后進行壓縮,其中為了避免出現(xiàn)壓縮絕對路徑的情況,direct1,direct2,test.txt使用的都是相對路徑,直接鼠標雙擊該test.bat運行OK,放在QT中運行OK,似乎完美的解決了問題。

但是我發(fā)現(xiàn),如果目錄中出現(xiàn)()括號字符就不行了,當有括號字符的時候在QProcess執(zhí)行的報錯中顯示路徑被括號截斷,此后我把路徑用引號引起來沒效果:

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

根據(jù)網(wǎng)上搜索到的信息,用^符號對括號進行轉義沒有截斷的報錯了,但是命令執(zhí)行還是沒有效果,控制臺也沒有報錯:

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

到這里我不知道該怎么樣去達到我的效果,唯一的感覺QProcess怎么這么難用,如果有知道的QT大神,煩請告訴一下。我想到用另外一種方式來實現(xiàn),就是用C++寫一個dll實現(xiàn),然后QT中調(diào)用。

在QT中調(diào)用C++創(chuàng)建的dll

主要代碼如下,實際上就是調(diào)用system函數(shù),但是如果路徑中有圓括號,還是需要用^符號進行轉義,否則system執(zhí)行也有問題:


void SystemTool::GenerateIndexRar(char * command)

{

    if(command == NULL) return ;

    system(command);

}

但是除了圓括號要轉義以外,還存在一個很不舒服的問題,就是每次執(zhí)行都會彈出cmd的黑窗口,執(zhí)行完成之后,窗口消失,代碼改成下面的就好了:


#include <windows.h>

void SystemTool::GenerateIndexRar(char * command)

{

if(command == NULL) return ;

/**

WinExec 的windows 調(diào)用,可以通過參數(shù)SW_HIDE隱藏命令行黑窗口

并且命令的路徑是可以帶括號的

*/

WinExec(command,SW_HIDE);

}

到此完美解決該問題,既不需要對圓括號進行轉義,同時也隱藏了黑窗口了。當然前述的test.bat的內(nèi)容要在程序中動態(tài)生成,利用合適的路徑替換掉test.bat中的路徑。

最后調(diào)用如:SystemTool::GenerateIndexRar("E:/test_rar_course(xx)/test.bat");

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI