延续前面从QProcess说开来(一)的名字,换个角度继续学习。
QIODevice派生类
QProcess作为QIODevice的派生类,实现角度上看,它必须要重新实现下面两个成员函数:
而后,按照QIODevice的常规用法,我们
- 调用QIODevice::open()打开设备
- 使用QIODevice::read()/QIODevice::write()读写
- 使用QIODevice::close()关闭
实际上,我们的常规用法是:
常用代码
|
其调用父类成员
|
QProcess::start()
|
QIODevice::open()
|
QProcess::readAllStandardError()
|
QIODevice::readAll()
|
QProcess::readAllStandardOutput()
|
QProcess::write()
|
QIODevice::write()
|
QProcess::close()
|
QIODevice::close()
|
除此以外,QProcess还有静态成员函数可用:
- QProcess::execute() 启动一个进程,然后等待该进程结束。
- QProcess::startDetached() 启动一个进程,然后使其和当前进程脱离进程的父子关系。
不过:这两种用法应该和QIODevice的提供的功能关系不大了。
启动
我只有ubuntu和windows系统,下面的内容也就不会超出这两个系统的范围。 dbzhang800 20110116
Unix
系统的2个api函数与此有关:
fork()
|
用来创建新进程
|
linux下的api函数clone()有类似功能,似乎主要用于构建线程
|
execve()
|
用来执行新程序
|
它还有5个马甲(库函数)
execl() execv()
execlp() execvp()
execle()
|
这个execve()对我们使用QProcess应该比较重要,因为我们启动参数都是要传递给它的:
int execve(const char *filename, char *const argv[], char *const envp[]);
filename
|
如果包含“/”,则视为路径名;否则按照PATH环境变量指定的目录进行搜索。filename可以是解释器文件(首行是#!/usr/bin/python这种)
|
argv
|
命令行参数列表
|
envp
|
环境变量列表。比如:有时可能会考虑像Windows那样将当前路径也加入PATH环境变量
|
而 QProcess::startDetached() 在Unix下创建的是一个孤儿进程:
- 当前进程P下 fork() 得到子进程 C1
- C1下 fork() 得到 子子进程 CC1
- C1自愿结束,CC1调用execve执行外部程序且与进程P脱离关系
在Unix下,还有system()、popen()等库函数也可以用来启动外部程序。
Windows
和Unix下完全不同,Windows进程创建的api函数是一个带有众多参数的CreateProcess
BOOL CreateProcess(
PCTSTR pszApplicationName,
PTSTR pszCommandLine,
PSECURITY_ATTRIBUTES psaProcess,
PSECURITY_ATTRIBUTES psaThread,
BOOL bInheritHandles,
DWORD fdwCreate,
PVOID pvEnvironment,
PCTSTR pszCurDir,
PSTARTUPINFO psiStartInfo,
PPROCESS_INFORMATION ppiProcInfo);
看着就头大,看个小例子吧:
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
TCHAR commandLine[] = TEXT("notepad.exe");
CreateProcess(NULL, commandLine, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
只看一个单纯和启动有关的(即和前面的fork/execve参数对应的):
按照Windows核心编程一书中说法,99%的情况下,我们都是直接传递一个NULL给它。它存在的原本目的是为了支持Windows的posix子系统。
如果指定了这个参数:程序名后缀必须指定;而且不在当前工作路径下的话,必须指定全路径。
注:Qt在WindowCE下的实现在使用这个参数。
如果前一个参数为NULL,则该字符串参数中第一个空格(被双引号括住的不算)前的内容则为应该程序的程序名。
如果程序名不包含路径,则按照下列顺序查找:
- 当前进程的程序文件的所在目录
- 当前进程的工作目录
- Windows的system32目录
- Windows目录
- 环境变量PATH中的目录
注意,这是一个字符串。而在unix下,是一个字符串的列表。所在当参数中包含空格等东西时,在Windows下总是需要特殊处理。
环境变量
指定工作目录,这个前面没提到。因为在unix下,分成fork()/execve()两个阶段,在fork()之后直接调用chdir设置进程的工作目录即可。
同样,看一下 QProcess::startDetached()的情况:
|
BOOLbInheritHandles
|
|
QProcess::startDetached()
|
FALSE
|
父进程CreateProcess后立即调用CloseHandle关闭持有的子进程的线程和进程句柄
|
QProcess::start()
|
TRUE
|
|
进程终止
看完启动,简单看看终止(termination)。
在C1X和C++11标准之前,C/C++标准中没有线程相关的东西。于是和进程终止相关的函数比较简单:
- main 函数中的 return
- exit()
- _Exit()
- abort()
接下来也不考虑多线程的情况(因为我理不太清)。这样一来,只用简单考虑:
自愿结束的我们一般不关心,所以只能后一个。在QProcess中,则对应:
- QProcess::kill()
- QProcess::terminate()
- QProcess::close()
其中 QProcess::close() 调用 QProcess::kill()
unix
在unix下,这是通过kill发送信号实现的
int kill(pid_t pid, int sig);
QProcess::kill()
|
发送 ::kill(pid, SIGKILL)
|
QProcess::terminate()
|
发送 ::kill(pid, SIGTERM)
|
进程结束后,会向其父进程发送 SIGCHLD 信号。父进程调用wait函数来获取进程该状态
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
windows
Windows下进程终止的api函数是
BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode);
QProcess::kill()调用是该函数。而QProcess::terminate()采用的却是另一个东西
-
采用 EnumWindows() 枚举进程内各个顶级窗口
-
对各个窗口使用 PostMessage() 发送 WM_CLOSE 消息
-
使用 PostThreadMessage() 对其主线程发送 WM_CLOSE 消息
分享到:
相关推荐
利用QProcess调用系统cmd程序实现ping功能,同时解决QT5中中文不能正常显示的问题
通过QT中的QProcess实现一个命令行,粗略版本 博客地址:https://tinycool.blog.csdn.net/article/details/124397664
QT+QProcess+进程双向通信
qt使用QProcess实现父子进程通信
QProcess 实现父子进程间的双向通信。子进程获取父进程write发送的数据。windows下测试通过
演示QProcess的使用方法,在QT中直接打开word文档,并且考虑了指令中含有汉字的处理,和含有空格的处理。并考虑了内存释放
在做系统集成框架软件时,经常遇到需要将已有程序的界面嵌入到统一框架软件的情形,该示例程序演示了在Qt5平台下面,使用QProcess启动并嵌入带界面应用程序的方法。该方法在Windows、Linux等操作系统下测试通过,...
QT 中QProcess模块的较全面资料,适合于编程查询和学习
QT通过QProcess调用外部程序 博客地址:https://tinycool.blog.csdn.net/article/details/124359078
非常简单的代码,仅仅实现了qt调用mplayer,能播放代码包中提供的 0.mp3。亲测没问题。如果下载后不能正常播放,请检查mplayer是否能正常使用。
QT通过QProcess调用外部可执行程序,并将其嵌入到主窗口中.7z
Qt案例之利用QProcess类实现启动进程的功能进阶(以dos命令dir为例),详细内容可参考文章:https://blog.csdn.net/didi_ya/article/details/123180765
QT通过QProcess调用外部可执行程序,并将其嵌入到主窗口中,代码完整,可执行运行
使用qt5实现qprocess功能,亲测有效,希望对初学者有帮助
Qt5案例之利用QProcess获取计算机硬件信息,介绍利用QProcess获取计算机的CPU、主板、硬盘等电脑相关硬件信息。windows提供了“wmic”(Windows Management Instrumentation,Windows管理工具),提供了从命令行接口...
《C++ Qt开发:QProcess进程管理模块》文章课件
Qt6案例之利用QProcess获取计算机硬件信息,介绍利用QProcess获取计算机的CPU、主板、硬盘等电脑相关硬件信息。windows提供了“wmic”(Windows Management Instrumentation,Windows管理工具),提供了从命令行接口...
Qt实战案例之利用QProcess实现应用程序重启功能.zip,可参考文章:https://wendy.blog.csdn.net/article/details/126087475
通过QProcess 调用 ffmpeg指令,检测max_volume小于0的文件,拿到文件列表,再通过ffmpeg指令来提高音频。
Qt实战案例之利用QProcess获取计算机硬件信息,可参考文章:https://blog.csdn.net/didi_ya/article/details/125129207