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());
版权声明:本文为博主原创文章,转载请附上博文链接!