qt/C++下windows远程控制开关机(附源代码)

 1、windows下要实现远程控制开关机,需要对系统进行相关的配置,否则远程控制失败;

2、windows的远程配置请参考电脑LAN远程开关机配置(windows11家庭版)_windows 远程开机-优快云博客

3、以下是具体实现代码如下:

头文件

#include <Windows.h>
#include <stdio.h>

#include <QObject>
#include <QProcess>

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "advapi32.lib")


class CRemoteControl : public QObject
{
	Q_OBJECT

public:
	CRemoteControl(void);
	~CRemoteControl(void);

public:
	static int StartupPC(char *chMac);
	static int ShutdownPC(char *chIP, int iTimeOut, bool bForceAppsClosed, bool bRebootAfterShutDown);
	static void remoteClose(QString str);
	static bool pingIPState(QString str);
};

源文件

#include "CRemoteControl.h"

CRemoteControl::CRemoteControl()
{

}

CRemoteControl::~CRemoteControl()
{

}

int CRemoteControl::StartupPC(char *chMac)
{
	//判断Mac地址格式
	for (char *a = chMac; *a; a++)
	{
		if (*a != '-' && !isxdigit(*a))
		{
			OutputDebugStringA("Mac address must be like this: 00-d0-4c-bf-52-ba");
			return -1;
		}
	}

	//字符串转数组
	int dstaddr[6];
	int i = sscanf_s(chMac, "%2x-%2x-%2x-%2x-%2x-%2x", &dstaddr[0], &dstaddr[1], &dstaddr[2], &dstaddr[3]
		, &dstaddr[4], &dstaddr[5]);


	if (i != 6)
	{
		OutputDebugStringA("Invalid mac address!");
		return -1;
	}

	//构造Magic Packet (包格式: "FFFFFFFFFFFF" + 重复16编mac地址)
	unsigned char ether_addr[6];
	for (i = 0; i < 6; i++)
	{
		ether_addr[i] = dstaddr[i];
	}

	u_char magicpacket[200];
	memset(magicpacket, 0xff, 6);
	int packetsize = 6;
	for (i = 0; i < 16; i++)
	{
		memcpy(magicpacket + packetsize, ether_addr, 6);
		packetsize += 6;
	}

	//创建广播套接字
	WSADATA WSAData;
	if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)
	{
		OutputDebugStringA("WSAStartup failed");
		return -1;
	}

	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
	{
		OutputDebugStringA("Socket Create error");
		return -1;
	}

	BOOL bOptval = TRUE;
	int iOptLen = sizeof(BOOL);
	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&bOptval, iOptLen) == SOCKET_ERROR)
	{
		OutputDebugStringA("setsocketopt error!");
		closesocket(sock);
		WSACleanup();
		return -1;
	}

	sockaddr_in to;
	to.sin_family = AF_INET;
	to.sin_port = htonl(0);
	to.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);

	//发送魔法包
	if (sendto(sock, (const char*)magicpacket, packetsize, 0, (const struct sockaddr*)&to, sizeof(to)) == SOCKET_ERROR)
	{
		OutputDebugStringA("Send error!");
	}
	else
	{
		OutputDebugStringA("Send success!");
	}

	closesocket(sock);
	WSACleanup();
	return 0;
}


void CRemoteControl::remoteClose(QString str)
{

    QProcess* cmd = new QProcess();		
	QString cmdstr = QString("shutdown /m \\\\%1 /s /f /t 1").arg(str);		
	cmd->start(cmdstr); // 等待ping 的结果 
	cmd->waitForReadyRead(100);
	cmd->waitForFinished(100);
	cmd->close();
	cmd->kill();
	delete cmd;
	
}

bool CRemoteControl::pingIPState(QString str)
{
	bool ret = false;
	QProcess* cmd = new QProcess();
	QString cmdstr = QString("ping %1 -n 1 -w %2").arg(str).arg(200);
	cmd->start(cmdstr); // 等待ping 的结果 
	cmd->waitForReadyRead(100);
	cmd->waitForFinished(100);
	QString result = cmd->readAll();
	if (result.indexOf("TTL") == -1)
	{
		ret = false;
	}
	else
	{
		ret = true;
	}
	cmd->close();
	cmd->kill();
	delete cmd;
	return ret;
}

4、调用远程开关机代码如下

/*关机*/
if (CRemoteControl::pingIPState(ui.label_ipAddress->text()))
{
	CRemoteControl::remoteClose(ui.label_ipAddress->text());
}
CRemoteControl::StartupPC((char*)m_macAddress.toStdString().data());

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值