qt/C++下远程控制软件启动和关闭(附源代码)

1、由于没有直接的方法远程控制软件,因此需要在软件被控制端,开发一个远程控制的客户端。

2、客户端代码如下:

头文件

#include <QtWidgets/QWidget>

#include <QSettings>
#include <QProcess>
#include <QDebug>
#include <QMessageBox>
#include <QUdpSocket>

struct softwareControlStuct
{
	char	header;	//固定为0xff
	char	name[128];	//软件名字
	bool	isRunning;	//启动还是关闭
	char	check;	//所有字节和的低位
};


class remoteControlSoftwareClient : public QWidget
{
    Q_OBJECT

public:
    remoteControlSoftwareClient(QWidget *parent = nullptr);
    ~remoteControlSoftwareClient();

private:
	void readIniFile();
	void networkInit(int port);
	void sendData(QString data);
	void readData(QByteArray data);
	void startProgram(const QString &program);
	void shutdownProgram(const QString &program);
	bool check_sum(QByteArray data);
public slots:
	void readyRead();
private:
    Ui::remoteControlSoftwareClientClass ui;
	QUdpSocket *socket = nullptr;
	int		port = 0;
};

源文件

#include "remoteControlSoftwareClient.h"

remoteControlSoftwareClient::remoteControlSoftwareClient(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
	readIniFile();
	networkInit(port);
}

remoteControlSoftwareClient::~remoteControlSoftwareClient()
{
	if (socket != nullptr)
	{
		socket = nullptr;
	}
}
/*读取配置文件*/
void remoteControlSoftwareClient::readIniFile()
{
	QSettings setting(QApplication::applicationDirPath() + "./config.ini", QSettings::IniFormat);
	port = setting.value("UDP/port").toString().toInt();
}
/*udp初始化*/
void remoteControlSoftwareClient::networkInit(int port)
{
	socket = new QUdpSocket(this);
	bool ret = socket->bind(port);
	if (!ret)
	{
		QMessageBox::warning(this, tr("error"), tr("UdpSocket create error!"));
	}
	connect(socket, &QUdpSocket::readyRead, this, &remoteControlSoftwareClient::readyRead);
}
void remoteControlSoftwareClient::sendData(QString data)
{
	if (socket != nullptr)
	{
		socket->write(data.toUtf8().constData());
	}
}
/*接收数据*/
void remoteControlSoftwareClient::readyRead()
{
	if (socket != nullptr)
	{
		while (socket->hasPendingDatagrams()) {
			QByteArray datagram;
			datagram.resize(socket->pendingDatagramSize());
			socket->readDatagram(datagram.data(), datagram.size());
			readData(datagram);
		}
	}
}
/*处理接收数据*/
void remoteControlSoftwareClient::readData(QByteArray data)
{
	bool	checked = check_sum(data);/*计算校验*/
	if ((quint8)data[0] == 0xFF && checked)/*固定头0xFF*/
	{
		softwareControlStuct m_softwareControlStuct;
		memcpy(&m_softwareControlStuct, data, sizeof(softwareControlStuct));

		if (m_softwareControlStuct.isRunning == 1)
		{
			startProgram(m_softwareControlStuct.name); // 启动程序
		}
		else if (m_softwareControlStuct.isRunning == 0)
		{
			shutdownProgram(m_softwareControlStuct.name); // 关闭程序
		}
	}
}
/*启动程序的函数*/
void remoteControlSoftwareClient::startProgram(const QString &program)
{
	//启动指定文件夹下的软件
	QProcess process;
	process.start(program); // 启动指定软件
	if (process.waitForStarted()) {
		qDebug() << "Application started successfully";
	}
	else {
		qDebug() << "Failed to start application";
	}
}
/*关闭程序的函数*/
void remoteControlSoftwareClient::shutdownProgram(const QString &program) 
{
	// 这里假设你有一个方法来找到该程序的进程ID
	QProcess process;
	process.start("tasklist", QStringList() << "/FI" << "\"IMAGENAME eq %1\"" << "|" << "findstr" << "\"%1\"");
	process.waitForFinished(); // 等待命令执行完毕
	QString output = process.readAllStandardOutput();
	bool found = false;
	int pid = 0;
	QStringList lines = output.split("\r\n"); // 在Windows上,需要处理行结束符
	for (const QString &line : lines) {
		if (line.contains(program)) {
			QStringList parts = line.split(QRegExp("\\s+")); // 使用正则表达式来分割字符串
			pid = parts.value(1).toInt(); // 假设PID是第二列
			found = true;
			break;
		}
	}
	if (found)
	{
		process.start("taskkill", QStringList() << "/F" << "/PID" << QString::number(pid));
		process.waitForFinished(); // 等待命令执行完毕
		qDebug() << program << "已关闭,进程ID为" << pid;
	}
	else
	{
		qDebug() << program << "未运行";
	}
}

/*udp通信数据校验和(除最后一个字节外的所有字节和的低8位)*/
bool remoteControlSoftwareClient::check_sum(QByteArray data)
{
	unsigned long sum = 0;
	for (int i = 0; i < data.length() - 1; i++)
	{
		sum += data[i];
	}
	unsigned int check = sum >> 8;
	if (check == data[data.length()])
	{
		return true;
	}
	else
	{
		return false;
	}
}

3、远程控制端代码如下

bool CRemoteControl::controlSoftware(QString ip, int port, QString cmd)
{
	QUdpSocket socket;
	socket.connectToHost(ip, port);
	if (socket.waitForConnected(1000)) {
		if (cmd == "start")
		{
			socket.write("start");
		}
		else if (cmd == "stop")
		{
			socket.write("stop");
		}
	}
	socket.waitForBytesWritten(1000);
	socket.waitForReadyRead(1000);
	QByteArray data = socket.readAll();
	bool result = false;
	if ((QString(data) =="Software started" && cmd == "start") || (QString(data) == "Software stopped" && cmd == "stop"))
	{
		result = true;
	}
	else
	{
		result = false;
	}

	return result;
}
/*开启*/
isRunState = CRemoteControl::controlSoftware(remoteIpAddress, remotePort, "stop");
/*关闭*/
isRunState = CRemoteControl::controlSoftware(remoteIpAddress, remotePort, "start");

版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值