QProcess:在QT中调用外部程序(也是QT写的程序)(1)
QT调用外部程序有三种大的方法:
(1)通过调用系统函数,system阻塞调用,WinExec非阻塞调用:
1、system("notepad.exe"); // 阻塞式调用
system函数可以调用外部程序,要以.exe为结尾,也就是完整的可执行文件名。调用时,它先调用cmd.exe,再由cmd中调用notepad.exe。所以执行这条语句时,可以看到cmd的窗口,然后再看到notepad(记事本)打开。同时原有进程被阻塞,只有关闭notepad后,才可以关闭调用的主进程。另外需要说明的是,调用的可执行路径的名称中不能有空格,否则cmd解释时会报错。如下面的网易云音乐执行时就会报错。
“C://Program Files (x86)//Netease//CloudMusic//cloudmusic.exe”
还有一点,就是路径中的"\\"。但这可能是我的错误习惯造成的,一定要用"//"。正确写法如下:“C://Netease//CloudMusic//cloudmusic.exe”
2、WinExec("mydirectory\\myApp.exe",SW_SHOW); // 非阻塞式调用
首先,调用此函数时,要包括头文件#include <Windows.h>。
第二,WinExec主要运行EXE文件,不能运行其他类型的文件。不用引用特别单元。
UINT WinExec(exePath,ShowCmd);
第一个参数exePath是命令行参数。注意,可能要用pChar转化一下。第二个参数ShowCmd的用法如下:
----SW_HIDE 隐藏
----SW_MAXIMIZE 最大化
----SW_MINIMIZE 最小化,并把Z order顺序在此窗口之后(即窗口下一层)的窗口激活
----SW_RESTORE 激活窗口并还原为初始化大小 SW_SHOW 以当前大小和状态激活窗口
----SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
----SW_SHOWDEFAULT 以默认方式运行
----SW_SHOWMAXIMIZED 激活窗口并最大化
----SW_SHOWMINIMIZED 激活窗口并最小化
----SW_SHOWMINNOACTIVE 最小化但不改变当前激活的窗口
----SW_SHOWNA 以当前状态显示窗口但不改变当前激活的窗口
----SW_SHOWNOACTIVATE 以初始化大小显示窗口但不改变当前激活的窗口
----SW_SHOWNORMAL 激活并显示窗口,如果是最大(小)化,窗口将会还原。
WinExec("运行程序的路径/文件名.exe --有需要可以加启动命令",SW_SHOW);
第三,WinExec执行时非阻塞式调用。可以关闭调用的主进程,而被调用的进程依然运行。据参考的博客说这种调用方法兼容性不好。考虑进程之间的参数传递,我不打算用这类系统函数调用的方式,所以不进一步研究了。
关于系统函数的调用还有两个函数,参考这篇博客:
参考这篇博客qt中ShellExecute、ShellExecuteEx和WinExec的用法和区别_qt shellexecute_东方忘忧的博客-CSDN博客
(2)通过QProcess,阻塞调用
1、QProcess::execute("c:\\mydirectory\\myApp.exe"); //绝对路径和相对路径都可以
windows下要带exe后缀,系统应用如记事本notepad可直接输入打开。
但这个函数如同system的系统调用,完全阻塞,子进程一旦运行,不可操作主进程。直到子进程退出。
2、QProcess::startDetached() 启动一个进程,然后使其和当前进程脱离进程的父子关系。
这是个不完全阻塞的调用方式。子进程调用运行后,主进程没有被阻塞操作,可以关闭主进程,而且关闭主进程后,子进程可以继续运行。应该是一种分离式的运行。
(3)通过QProcess,非阻塞调用
QProcess *pro = new QProcess;
pro->start("c:\\mydirectory\\myApp.exe");
上面用QProcess的start()函数,运行后是一个非阻塞调用。子进程运行时,主进程可以关闭。并且主进程关闭时,子进程也被关闭。
但如果加上下面的语句,QProcess的start()函数,也能够变成阻塞式调用。也就是子进程运行时,主进程不可操作,不能退出,必须等待子进程结束。
QProcess *pro = new QProcess;
pro->start("c:\\mydirectory\\myApp.exe");
pro->waitForFinished(); // 变成阻塞
Sleep(1000); // 等待子进程运行的估计时间。
由于我希望子进程与主进程有更好的沟通方式,如主进程向子进程传递参数,子进程向主进程报告运行结果。所以,我选择“通过QProcess的非阻塞调用”的方式。后继的文章将记录使用这种方式的详细研究过程和结果。