Qt-QProcess-启动子进程-控制台进程隐藏-获取子进程标准输出和返回码

news2024/12/25 8:59:08

文章目录

    • 1.隐藏控制台程序
      • 1.1.控制台程序生成即隐藏
      • 1.2.调用程序隐藏控制台
    • 2.QProcess
      • 2.1.基础用法-start和startDetached
      • 2.2.获取子进程的标准输出
    • 3.代码范例
      • 3.1.等待进程执行完毕,获取所有的输出
      • 3.2.子进程返回信号
      • 3.3.进程是否启动
      • 3.4.执行命令行
      • 3.5.与子进程交互
    • 4.作者答疑

1.隐藏控制台程序

1.1.控制台程序生成即隐藏

创建控制台项目,修改项目属性,然后在子系统中选择链接器》系统 选择窗口子系统,下面高级中,入口点选择mainCRTStartup,如下图所示:
在这里插入图片描述
在这里插入图片描述
这样生成的程序,窗口需要程序编码创建,不创建则没有窗口,从而达到无显示的隐藏效果。

1.2.调用程序隐藏控制台

在父进程调用时,即指定隐藏控制台窗口,注意这种模式对于窗口子系统是不能隐藏的。

#include "windows.h"
#include <iostream>
//执行并等待控制台程序
static DWORD ExecAndWaitConsole(LPCTSTR lpszAppPath, LPCTSTR lpParameters, LPCTSTR lpszDirectory, DWORD dwMilliseconds)
{
	SHELLEXECUTEINFO ShExecInfo = { 0 };
	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
	ShExecInfo.hwnd = NULL;
	ShExecInfo.lpVerb = NULL;
	ShExecInfo.lpFile = lpszAppPath;
	ShExecInfo.lpParameters = lpParameters;
	ShExecInfo.lpDirectory = lpszDirectory;
	ShExecInfo.nShow = SW_HIDE;
	ShExecInfo.hInstApp = NULL;
	if (!ShellExecuteEx(&ShExecInfo))
	{
		return 0;
	}
	// 指定时间没结束
	if (WaitForSingleObject(ShExecInfo.hProcess, dwMilliseconds) == WAIT_TIMEOUT)
	{    // 强行杀死进程
		TerminateProcess(ShExecInfo.hProcess, 0);
		return 0;    //强行终止
	}
	DWORD dwExitCode;
	if (!GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode))
	{
		return 0;
	}
	return dwExitCode;
}
int main()
{
	ExecAndWaitConsole(L"console1.exe",
		NULL,
		NULL, 10000);
    std::cout << "Hello World!\n";
	Sleep(100000);
}

2.QProcess

QProcess是Qt提供的强大进程交互工具。简单的进程调用,采用上述模式即可解决,而父子进程之间更复杂的交互,QProcess提供了更好的解决方案。

2.1.基础用法-start和startDetached

start是一体式的:外部程序启动后,将随主程序的退出而退出;
startDetached是分离式的:外部程序启动后,不会随主程序的退出而退出。
重要区别:如果是start则回调都可以正常接收到信息;如果是startDetached则回调无法正常接收到信息。
如果是简单调用,建议采用startDetached,需要获取进程执行的各种状态,建议采用start。QProcess启动的控制台程序,都是隐藏窗口。范例代码如下:

#include <QProcess>
static void TestStartDetached(){
	//startDetached是个静态函数,可以直接调用,一共有四种形式
	QProcess::startDetached(QString::fromLocal8Bit("./TestConsoleApplication1.exe"));
	QProcess::startDetached(QString::fromLocal8Bit("./TestConsoleApplication1.exe"), 
		QStringList() << "para1" << "para2");
}

static void TestStart(){
	QProcess* tQProcess = new QProcess;
	//子进程会随着tQProcess的销毁而关闭,如果不想随着函数的调用结束而关闭,需要在堆上申请内存。
	tQProcess->start(QString::fromLocal8Bit("./TestConsoleApplication1.exe"),
		QStringList()<<"para1"<<"para2"	);
	//tQProcess->deleteLater();
}

static void TestStart2(){
	//显示窗口-极少使用
	QProcess *tQProcess = new QProcess();
	tQProcess->start("cmd.exe");
	tQProcess->write("cd /d E:/work/CurrentProject/微博/QtConnect/x64/Release && start TestConsoleApplication1.exe\n");
}

2.2.获取子进程的标准输出

进程具有两个预定义的输出通道:标准输出通道(stdout)提供常规控制台输出。标准错误通道(stderr)通常提供由进程打印的错误。
这些通道代表两个单独的数据流,可以通过调⽤setReadChannel()函数在它们之间切换。当前读取通道上有可⽤数据时,QProcess发出readyRead()信号。当有新的标准输出数据可⽤时,它也会发出readyReadStandardOutput()信号,⽽当有新的标准错误数据可⽤时,它会发出readyReadStandardError()信号。⽆需调⽤read()函数,readLine()函数或getChar()函数,⽽是可以通过调⽤readAllStandardOutput()函数或readAllStandardError()函数显式地从两个通道之⼀读取所有数据。

进程同步API
waitForStarted()函数——阻塞直到进程开始。
waitForReadyRead()函数——阻塞直到有新数据可在当前读取通道上读取为⽌。
waitForBytesWritten()函数——阻塞直到将⼀个有效载荷数据写⼊该进程为⽌。
waitForFinished()函数——阻塞直到过程完成。

3.代码范例

3.1.等待进程执行完毕,获取所有的输出

代码如下所示:

#include <qDebug>
#include <QProcess>
static void TestGetOutData(){
	QProcess process;
	process.start("ping www.baidu.com");
	process.waitForFinished();
	QByteArray allOutData = process.readAll();
	if (allOutData.isEmpty())
	{
		allOutData = process.readAllStandardOutput();
		if (allOutData.isEmpty())
		{
			allOutData = process.readAllStandardError();
		}
	}
	//中文乱码问题
	qDebug() << QString::fromStdString(allOutData.data());
}

3.2.子进程返回信号

进程结束,返回进程结束参数。

void QtConnect::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
	qDebug() << "finished";
	qDebug() << exitCode;// 被调用程序的main返回的int
	qDebug() << exitStatus;// QProcess::ExitStatus(NormalExit)
}

void QtConnect::Test() {
	QProcess* tQProcess = new QProcess;
	tQProcess->start(QString::fromLocal8Bit("E:/work/CurrentProject/微博/QtConnect/x64/Debug/TestConsoleApplication1.exe"));
	connect(tQProcess, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(finished(int, QProcess::ExitStatus)));
}

3.3.进程是否启动

void QtConnect::Test() {
	QProcess* tQProcess = new QProcess;
	tQProcess->start(QString::fromLocal8Bit("E:/work/CurrentProject/微博/QtConnect/x64/Debug/TestConsoleApplication1.exe"));
	if (!tQProcess->waitForStarted())
	{
		qDebug() << "成功!";
	}
	else
	{
		qDebug() << "失败!";
	}
}

3.4.执行命令行

void QtConnect::Test() {
	QStringList arguments;
	arguments << "/c" << "dir";//
	QProcess tProcess(this);
	tProcess.setProcessChannelMode(QProcess::MergedChannels);
	tProcess.start("cmd.exe", arguments);
	tProcess.waitForStarted();
	tProcess.waitForFinished();
	QString strResult = QString::fromLocal8Bit(tProcess.readAll());
	qDebug() << strResult;
}

3.5.与子进程交互

未来有需要再写,本质就是利用通道来进行数据的交互。

	QProcess gzip;
    gzip.start("gzip", QStringList() << "-c");
    if (!gzip.waitForStarted())
        return false;

    gzip.write("Qt rocks!");
    gzip.closeWriteChannel();

    if (!gzip.waitForFinished())
        return false;

    QByteArray result = gzip.readAll();

4.作者答疑

如有疑问,敬请留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GIT客户端安装

步骤1&#xff1a;运行“Git-2.13.1-64-bit.exe”&#xff0c;并点击“运行”按钮&#xff08;默认&#xff09;步骤2&#xff1a;许可信息页面&#xff0c;点击“Next”&#xff08;默认&#xff09;步骤3&#xff1a;选择安装路径&#xff08;默认&#xff09;步骤4&#xff…

记一次 .NET 某医保平台 CPU 爆高分析

一&#xff1a;背景 1. 讲故事 一直在追这个系列的朋友应该能感受到&#xff0c;我给这个行业中无数的陌生人分析过各种dump&#xff0c;终于在上周有位老同学找到我&#xff0c;还是个大妹子&#xff0c;必须有求必应 &#x1f601;&#x1f601;&#x1f601;。 妹子公司的…

IDEA高效插件和设置

安装好Intellij idea之后&#xff0c;进行如下的初始化操作&#xff0c;工作效率提升十倍。 一. 安装插件 1. Codota 代码智能提示插件 只要打出首字母就能联想出一整条语句&#xff0c;这也太智能了&#xff0c;还显示了每条语句使用频率。 原因是它学习了我的项目代码&…

力扣-从不订购的客户

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;183. 从不订购的客户二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果总结前言…

2月编程语言排行榜谁还没有看?

近日&#xff0c;TIOBE公布了2023年2月编程语言排行榜&#xff0c;本月各个语言表现如何&#xff1f;谁又摘得桂冠&#xff1f;一起来看看吧&#xff01; TIOBE 2月Top15编程语言&#xff1a; 详细榜单查看TIOBE官网 https://www.tiobe.com/tiobe-index/ 关注IT行业的小伙伴们…

Qt音视频开发15-动态切换解码内核的设计

一、前言 动态切换解码内核这个需求也是源自客户的真实需求&#xff0c;既然是动态切换&#xff0c;那肯定是运行期间切换&#xff0c;而不是通过改变标志位重新编译程序来切换&#xff0c;最开始做的就是这种方式&#xff0c;这样就是实现起来简单&#xff0c;但是用起来不够…

OpenGL ES基础简介

简介 视频的渲染源是 YUV 或者 RGBA 格式的数据&#xff0c;这种数据是描述画面最基础的格式&#xff0c;其中 YUV 常用在视频的原始格式中&#xff0c;RGBA 常用在一些图像的原始格式上。 目前各个平台最终渲染到屏幕上的都是 RGBA 格式的&#xff0c;因为硬件对屏幕上的设计…

【可视化实战】Python 绘制出来的数据大屏真的太惊艳了

今天我们在进行一个Python数据可视化的实战练习&#xff0c;用到的模块叫做Panel&#xff0c;我们通过调用此模块来绘制动态可交互的图表以及数据大屏的制作。 而本地需要用到的数据集&#xff0c;可在kaggle上面获取 https://www.kaggle.com/datasets/rtatman/188-million-us…

SpringBoot之DEBUG远程调试黑科技?

所谓的远程调试就是服务端程序运行在一台远程服务器上&#xff0c;我们可以在本地服务端的代码&#xff08;前提是本地 的代码必须和远程服务器运行的代码一致&#xff09;中设置断点&#xff0c;每当有请求到远程服务器时时能够在本地知道 远程服务端的此时的内部状态。 简单的…

计算机408考研先导课---C语言难点

以下为小编在重温C语言时&#xff0c;容易犯错的一些点&#xff0c;希望列出来对大家有一定帮助&#xff01; 一、整型变量数的范围 类型说明符长度&#xff08;字节&#xff09;数的范围int4/2&#xff08;有些为4字节&#xff0c;有些为2字节&#xff09;-32768~32767short2…

ArcMap出图小技巧:主图设计、图例、比例尺、指北针、标题

ArcMap一个重要的功能是出图&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 因为图片对于一些文字描述来说更为直观&#xff0c;所以掌握一些出图技巧也是极为重要的&#xff0c;不仅能让我们在数据处理过程快速得到我们想要的图层&#xff0c;也可以让图层看起…

Teradata退了? 无所谓,GBASE会出手

近期&#xff0c;就在2月15日&#xff0c;国内IT界有搞出个大瓜&#xff0c;Teradata以对中国当前及未来商业环境的不确定性&#xff0c;慎重考虑后决定退出中国运营&#xff0c;后续将进入中国公司关闭程序。Teradata是一家有着40多年历史的数据仓库企业&#xff0c;被业界专业…

动态规划从入门到精通-蓝桥杯

一、了解动态规划1.简单来说动态规划是一种状态转移与递推2.例题引入——最少硬币问题有多个不同面值的硬币(任意面值)&#xff1b; 数量不限&#xff1b; 输入金额S&#xff0c;输出最少硬币组合。 &#xff08;回顾用贪心求解硬币问题。&#xff09;贪心法硬币面值1、2、5。支…

2023年中职网络安全竞赛跨站脚本渗透解析-2(超详细)

跨站脚本渗透 任务环境说明:需求环境可私信博主! 服务器场景:Server2126(关闭链接)服务器场景操作系统:未知访问服务器网站目录1,根据页面信息完成条件,将获取到弹框信息作为flag提交;访问服务器网站目录2,根据页面信息完成条件,将获取到弹框信息作为flag提交;访问…

CenterMask paper笔记

CenterMask是一个anchor free的实例分割模型&#xff0c; 来自paper: CenterMask: Real-Time Anchor-Free Instance Segmentation 提起anchor free, 会想到FCOS模型&#xff0c;是用来目标检测的&#xff0c; 那么这里就用到了FCOS, 不过换了backbone, 在FCOS检测出目标框后&…

插装式比例插装阀比例节流阀比例顺序阀放大器

都是直动式&#xff0c;不需要最小先导压力以及先导流量。它们的动作执行都是基于平衡力的设计理念。&#xff08;电磁力能按比例地反作用于液压力&#xff09;所有的比例螺线管都是按照5000psi&#xff08;350bar&#xff09;的标准设计&#xff0c;所以这些阀的所有口都可以承…

卷积网络与全连接网络的区别

问题卷积神经网络是一类包含卷积计算且具有深度结构的前馈神经网络&#xff0c;是深度学习。卷积神经网络具有表征学习能力&#xff0c;能够按其阶层结构对输入信息进行平移不变分类&#xff0c;因此也被称为“平移不变人工神经网络。全连接神经网络是具有多层感知器的的网络&a…

vs2022 实现无线调试安卓(Windows)

文章目录VS安装安卓调试环境前提条件Android SDK 版本查看安卓开启无线调试开启开发者模式打开USB调试功能打开无线调试功能查看配对信息&#xff08;再次点击无限调试&#xff0c;不是switch开关&#xff09;准备电脑端输入adb命令配对安卓查看设备清单如果没有设备VS无线调试…

python--matplotlib(3)

前言 Matplotlib画图工具的官网地址是 http://matplotlib.org/ Python环境下实现Matlab制图功能的第三方库&#xff0c;需要numpy库的支持&#xff0c;支持用户方便设计出二维、三维数据的图形显示&#xff0c;制作的图形达到出版级的标准。 其他matplotlib文章 python--matpl…

C++性能白皮书

最近看完了《C性能白皮书》&#xff0c;这本书列出了一些性能优化的思路&#xff0c;不过只是一些指引&#xff0c;没有讲具体细节&#xff0c;我整理出了其中的关键点分享给大家&#xff1a; 硬件篇 作为一个程序员&#xff0c;想要性能优化&#xff0c;最好要了解些硬件&…