关机模式下,BIOS的电源管理菜单下有Remote Wake Up或Wake on LAN等类似选项的电脑才支持远程开机,若无此选项则不支持远程开机。(假如Remote Wake Up开启后不支持远程开机,请咨询硬件提供商)。
当电脑开机启动时,通过反复按键盘“DELETE”键或“F2”键,进入到主板BIOS设置界面。更多启动主板BIOS设置界面帮助,参考百度。
通常到“Power Managment(电源管理)”下寻找如下列选项:
"Boot on LAN";
"Wake on LAN";
"PME Event WakeUp",;
"Resume by MAC LAN";
"Wake-Up by PCI card";
"Wake Up On PCI PME";
"Power On by PCI Card";
"WakeUp by PME of PCI";
"Power On By PCI Devices";
"WakeUp by Onborad LAN";
"PEX boot";
"Resume By PCI or PCI-E Ddevice"或类似的东西,并可以启用它。
可视图形化的UEFI BIOS,可参考下列方式设置:
高级 > 高级电源管理(APM)> 开启 Resume By PCI or PCI-E Ddevice(由pci/pcie设备唤醒)选项。
1.以Dell320为例:
进入Power Management Setup——Remote Wake Up设为On
2.以Dell Latitude D630为例:
进入Power Management——Wake on LAN/WLAN——选择LAN or WLAN。
3.以Dell 1950为例:
将Pre-boot Wake On LAN设为Enable。
4.以联想主板为例:
进入Power——Automatic Power ON——Wake On LAN设为Enabled。
5.以华硕主板为例:
进入高级——高级电源管理——开启由PCI/PCIE设备唤醒选项。
6.以技嘉主板为例:
进入BIOS功能——网络启动——选择Legacy First或UEFI First选项。
7.以微星主板为例:
进入STANDARD mode——Setup Wake Up Configuration——选择Resume By PCI-E Device选项。
远程开机需要网卡保持待机,关机后网卡灯不亮,请检查主板是否开启节能模式。因各厂商对此功能名称定义不一,常见的节电功能选项:
1.假如有Low Power Mode选项,一定要设置为Off。
2.或者是ErP 和 EuP选项,设置为Disabled。
若主板设置后仍无法开机,请参考帮助。
备注:若无法确认BIOS是否包含可设置参数,请使用远程开机检测工具,在内网测试是否可以远程开机或者直接联系主板厂商确认您的设备是否支持远程唤醒!
远程开机需要网卡保持待机
远程开机需要网卡保持待机
远程开机需要网卡保持待机
即关机后网卡灯亮。
如果BIOS设置好,但是网卡灯不亮,就需要进入系统设置。
1 Windows系统:
如果你的系统显示都是英文如下
请更新最新网卡驱动,就会变为中文并有网络唤醒。
Win10的用户请看这:
检查网卡属性是否缺少网络唤醒。如是,请更新最新网卡驱动;
检查网卡属性后,还需要调整关机设置。
关机设置选项默认无法修改,需先点击更改当前不可用的设置。
2 Linux系统:
检查网卡是否支持唤醒功能,输入命令ethtool eth0 打印出网卡的信息。
Supports Wake-on 值为g,表示网卡支持远程开机;若为d,则不支持。
Wake-on值为g,表示网卡已开启远程唤醒功能;
若为d,则输入命令 ethtool -s eth0 wol g 开启。
命令执行后,输入ethtool eth0,检测是否成功开启wake on lan功能。
#pragma once
#include
#include
//#include
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "advapi32.lib")
class CRemoteControl
{
public:
CRemoteControl();
~CRemoteControl();
static int Startup(char *chMac);
static int Shutdown(char *chIP, int iTimeOut, bool bForceAppsClosed, bool bRebootAfterShutDown);
};
#include "CRemoteControl.h"
CRemoteControl::CRemoteControl()
{
}
CRemoteControl::~CRemoteControl()
{
}
int CRemoteControl::Startup(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(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;
}
int CRemoteControl::Shutdown(char * chIP, int iTimeOut, bool bForceAppsClosed, bool bRebootAfterShutDown)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
BOOL fResult;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return false;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
if (GetLastError() != ERROR_SUCCESS)
return false;
WCHAR wszIP[20];
memset(wszIP, 0, sizeof(wszIP));
MultiByteToWideChar(CP_ACP, 0, chIP, strlen(chIP) + 1, wszIP, sizeof(wszIP) / sizeof(wszIP[0]));
//发送指令,iTimeOut如果小于60,则对方机器关机前会显示“一分钟内关机”
fResult = ::InitiateSystemShutdown(wszIP, NULL, iTimeOut, bForceAppsClosed, bRebootAfterShutDown);
if (!fResult)
return false;
tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, false, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
if (GetLastError() != ERROR_SUCCESS)
return false;
return true;
}
以上为我总结并实践于windows,MAC远程开机可用。
内容出处:他人的代码,某公司的页面,某公司另一页面