【QT】QT调用外部exe程序的几种方式

最近有个想法,在写的qt程序内调用其他的exe文件,过程遇到了很多问题,在此记录一下自己用到且实验成功的几种方式,在此感谢一下一篇博文:
https://blog.csdn.net/hzd12368/article/details/90106184?ops_request_misc=&request_id=&biz_id=102&utm_term=qt%E5%B0%86%E4%B8%80%E4%B8%AAexe%E6%96%87%E4%BB%B6%E5%8A%A0%E8%BD%BD%E5%88%B0%E5%86%85%E9%83%A8&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-90106184.pc_search_es_clickV2&spm=1018.2226.3001.4187

参考了上面的博文后,自己试验了一些,总结了一下两种调用方式。
假设 我们要调用外部的extern.exe文件,而我们正在写的程序为current.exe

1.将要调用的extern.exe文件加载到current的源文件内:

因为我自己要调用的exe文件名为firmware_upgrade_v1.0.0.exe文件,所以添加的是这个文件。
在这里插入图片描述
关于资源文件exe.qrc的创建:
邮件项目列表Forms,点击添加新文件,然后选择以下选项:
在这里插入图片描述
因为这几天眼睛疼,所以使用了比较暗的主题,所以在图片内我用框框标示了。
之后就是添加文件,注意的是。添加的文件最好复制到你正在写的qt工程目录下,否则会报错提示你选择个适合的路径。
在这里插入图片描述
这个是添加exetern.exe文件的界面,我是添加好了的,新创建的资源文件是没有上图标示"1"处的文件夹的,需要点击添加前缀,它会自动添加"1”处的文件夹,后面再去添加文件。

好了,准备工作做完,说说怎么把这个资源文件调用起来。
相信很多人都看了用qprocess的类去调用某个路径下的exe文件,但对于添加到资源文件的这个exe并不适用。

我试了很多次,直接调用资源路径“:/new/prefix1/firmware_upgrade_v1.0.0.exe”的话,process返回的永远是false,也就是调用失败:
QString CMD = “:/new/prefix1/firmware_upgrade_v1.0.0.exe”;
QProcess process(this);
process.startDetached(CMD);
所以第一种方法就是重构exe文件,假设我们想调用A.exe文件,也通过上述方式将A.exe添加到了资源文件,直接通过process是调用不了这个A.exe文件,那么我们直接创建个B.exe文件,然后通过读写文件的方式将A.exe文件全部读取到B.exe文件内,再去直接执行B.exe文件,执行完后删除B.exe文件,事后了无痕。

代码不多,很简单:

 QString EXEName_src = ":/new/prefix1/firmware_upgrade_v1.0.0.exe";
 QString EXEName_Dst = "firmware_upgrade_v1.0.0.exe";
 QFile EXEFile_src(EXEName_src);
 QFile EXEFile_Dst(EXEName_Dst);

  if (EXEFile_Dst.open(QIODevice::WriteOnly)) {
  	if (EXEFile_src.open(QIODevice::ReadOnly)) {
     	QByteArray tmp = EXEFile_src.readAll();
     	EXEFile_Dst.write(tmp);
      }
   }
   EXEFile_Dst.close();
   EXEFile_src.close();
   QString CMD = EXEName_Dst;
   //执行CMD命令
    /*************非阻塞式调用***********/
    QProcess process(this);
    process.startDetached(CMD);
    QFile::remove(EXEName_Dst); //删掉exe文件

上述是非阻塞调用exe文件,但是非阻塞调用有个坏处,执行最后的删除B.exe文件时会失败,导致会在你当前路径下创建个B.exe文件且不会被删除,好处是你的主程序仍然在运行,事件之类的仍然可以运行。
另外两种是阻塞式调用,好处是你的主程序会被卡在这里,直到cmd指令框被退出。
贴出阻塞式代码:
代码1:

char* ptr;
QByteArray ba = CMD.toLocal8Bit(); //支持含中文
ptr = ba.data();
system(ptr);

这个使用系统指令去调用。
代码2:第二种还是process,只不过是阻塞式

 process.start(CMD);
 process.waitForFinished();

好了,上述的这种将外部EXE文件嵌入到当前qt程序中的方法就讲完了,值得注意的是,如果你的外部EXE文件如果比较大的话,编译的时候会报错,说你资源文件太大,超过内存啦,因为他的资源文件都是放在静态的数组里的,文件太大的话会报错,解决方法也有,在你的工程.pro文件内添加CONFIG += resources_big就OK啦:
在这里插入图片描述

2.通过相对路径调用外部EXE文件

第1种方式是将外部exe嵌入到你自己的qt程序内,有好处也有坏处,好处是最终只需要一个exe的包就行,坏处是这个exe的包相对较大,因为包含了你外部的那个exe文件。
这第二种方式就是调用外部相对路径的exe文件。
还是假设吧,假设需要调用的外部EXE文件名为A.exe,我们正在写的qt的exe文件为B.exe
1.我们需要设定好我们要调用的A.exe文件相对于我们的B.exe的位置,相信看官们都知道文件路径是个什么玩意,就不多解释相对路径是个什么概念了。
既然要调用相对路径的A.exe,那么我们就得直到我们的B.exe在哪,贴代码:

QString str = QApplication::applicationDirPath();

str内就是你当前的B.exe所在的路径,但是我们要调用的是A.exe,假设我把A.exe和B.exe放在了一个路径下,那就如下:

QString str = QApplication::applicationDirPath();
str += "/firmware_upgrade_v1.0.0.exe";

直接加上当前路径下的B.exe就行,之后很简单啦,process走起,完整代码:

QProcess process(this);
QString str = QApplication::applicationDirPath();
str += "/firmware_upgrade_v1.0.0.exe";
process.startDetached(str);

当然 ,你想吧A.exe放在其他文件夹下也行,不过程序也要改,也就是说你的B.exe程序内写的路径决定了A.exe文件必须相对B.exe放在哪。OK有问题评论区扣我,可能说的不是特别细。写下此博文也是记录生活怕自己以后忘了,看官们相互建议哈。

  • 63
    点赞
  • 239
    收藏
    觉得还不错? 一键收藏
  • 23
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值