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的非阻塞调用”的方式。后继的文章将记录使用这种方式的详细研究过程和结果。