一、需求
1、人在公司坐,昨晚写的文档放在家中电脑忘记Copy了,想要访问家中电脑拿到文档。
2、家中或公司中局域网内有某台电脑(或服务器)要开机,或者批量一键打开局域网内某些电脑
二、必备条件
1、网线连接电脑网口(wifi无线网卡无法网络唤醒)
2、网卡支持网络唤醒功能
三、设置
1、主板BIOS设置
目前测试过的主板:微星PRO Z690-A WIFI DDR4(MS-7D25)、技嘉B75M-D3V、技嘉B85M-D2V
下面以微星PRO Z690-A为例。
主板:微星PRO Z690-A WIFI DDR4
系统:Windows10
路由器:中兴AX5400,TPLink5600和7660
发包程序:C#,下面有源码,或者伸手党可以直接从下载链接获取发布好的应用程序
开机狂按Del键进入微星BIOS,其他品牌DEL, ESC, F1, F2, F8, F9, F10, F12
- 高级–整合周边设备–网卡ROM启动,设置为允许
- 高级–电源管理设置–Eup 2013,设置为禁止
- 高级–唤醒事件设置–PCIE设备唤醒,设置为允许
2、网卡(Windows)设置
- 控制面板–所有控制面板项–网络连接
- 在网卡适配器点击鼠标右键–属性,弹出的属性对话框中
- 选择网络选项卡–配置
- 选择高级选项卡,将
关机 网络唤醒
设置为开启,将魔术封包唤醒
设置为开启 - 电源管理选项卡,勾选下面三个选项,允许此设备唤醒计算机。
- 切换为电源管理选项,勾选允许此设备唤醒计算机。
- 关闭快速启动,右击开始按钮,点击“电源选项”,点击“选择电源按钮的功能”;点击“更改当前不可用的设置”,把“启用快速启动”勾选。(这条必须做)
3、后记
- 电脑网线连接网口处,电脑关机状态下有的会有黄灯常量,有的电脑不亮,都能唤醒
- 在设置网卡的时候发现没有
关机 网络唤醒
的选项的时候,有可能是网卡驱动或者网卡版本不同,没有此选项也能唤醒。
三、C#源码
伸手党可以直接从下载链接获取发布好的应用程序,下载地址:
https://download.csdn.net/download/hwt0101/86781647
-
using System;
-
using System.Collections.Generic;
-
using System.ComponentModel;
-
using System.Data;
-
using System.Drawing;
-
using System.Linq;
-
using System.Net;
-
using System.Net.NetworkInformation;
-
using System.Net.Sockets;
-
using System.Runtime.InteropServices;
-
using System.Text;
-
using System.Text.RegularExpressions;
-
using System.Threading.Tasks;
-
using System.Windows.Forms;
-
-
namespace
RemotePowerOn
-
{
-
public
partial
class
Form1 :
Form
-
{
-
//通过正则表达式设定MAC地址筛选标准,关于正则表达式请自行百度
-
const
string macCheckRegexString =
@"^([0-9a-fA-F]{2})(([/\s:-][0-9a-fA-F]{2}){5})$";
-
-
private
static
readonly Regex MacCheckRegex =
new Regex(macCheckRegexString);
-
public Form1()
-
{
-
InitializeComponent();
-
}
-
public static bool WakeUp(string mac)
-
{
-
//查看该MAC地址是否匹配正则表达式定义,(mac,0)前一个参数是指mac地址,后一个是从指定位置开始查询,0即从头开始
-
if (MacCheckRegex.IsMatch(mac,
0))
-
{
-
byte[] macByte = FormatMac(mac);
-
WakeUpCore(macByte);
-
return
true;
-
}
-
-
return
false;
-
-
}
-
-
private static void WakeUpCore(byte[] mac)
-
{
-
//发送方法是通过UDP
-
UdpClient client =
new UdpClient();
-
//Broadcast内容为:255,255,255,255.广播形式,所以不需要IP
-
client.Connect(System.Net.IPAddress.Broadcast,
40000);
-
//下方为发送内容的编制,6遍“FF”+17遍mac的byte类型字节。
-
byte[] packet =
new
byte[
17 *
6];
-
for (
int i =
0; i <
6; i++)
-
packet[i] =
0xFF;
-
for (
int i =
1; i <=
16; i++)
-
for (
int j =
0; j <
6; j++)
-
packet[i *
6 + j] = mac[j];
-
//唤醒动作
-
int result = client.Send(packet, packet.Length);
-
}
-
-
private static byte[] FormatMac(string macInput)
-
{
-
byte[] mac =
new
byte[
6];
-
-
string str = macInput;
-
//消除MAC地址中的“-”符号
-
string[] sArray = str.Split(
'-');
-
-
-
//mac地址从string转换成byte
-
for (
var i =
0; i <
6; i++)
-
{
-
var byteValue = Convert.ToByte(sArray[i],
16);
-
mac[i] = byteValue;
-
}
-
-
return mac;
-
}
-
private void button1_Click(object sender, EventArgs e)
-
{
-
string mac = textBox1.Text;
-
WakeUp(mac);
-
//WakeUp("25-D5-47-12-97-E2");
-
}
-
-
-
private void button2_Click(object sender, EventArgs e)
-
{
-
#region 方法1
-
-
// TODO: Implement Functionality Here
-
// Get my PC IP address
-
Msg(
string.Format(
"My IP : {0}", GetIPAddress()));
-
// Get My PC MAC address
-
Msg(
string.Format(
"My MAC: {0}", GetMacAddress()));
-
// Get My PC HostName
-
Msg(
string.Format(
"My HostName: {0}", Dns.GetHostName()));
-
// Get all devices on network
-
Dictionary<IPAddress, PhysicalAddress> all = GetAllDevicesOnLAN();
-
foreach (KeyValuePair<IPAddress, PhysicalAddress> kvp
in all)
-
{
-
Msg(
string.Format(
"IP : {0}\n MAC {1}", kvp.Key, kvp.Value));
-
}
-
-
#endregion
-
-
#region 方法2
-
//GetIPAddress2();
-
//foreach (var ip in ips)
-
//{
-
// //Console.WriteLine(ip);
-
// Msg(ip);
-
//}
-
#endregion
-
}
-
-
#region MAC扫描方法1
-
//public static void Main(string[] args)
-
//{
-
// Console.WriteLine("Hello World!");
-
-
// // TODO: Implement Functionality Here
-
// // Get my PC IP address
-
// Console.WriteLine("My IP : {0}", GetIPAddress());
-
// // Get My PC MAC address
-
// Console.WriteLine("My MAC: {0}", GetMacAddress());
-
// // Get My PC HostName
-
// Console.WriteLine("My HostName: {0}", Dns.GetHostName());
-
// // Get all devices on network
-
// Dictionary<IPAddress, PhysicalAddress> all = GetAllDevicesOnLAN();
-
// foreach (KeyValuePair<IPAddress, PhysicalAddress> kvp in all)
-
// {
-
// Console.WriteLine("IP : {0}\n MAC {1}", kvp.Key, kvp.Value);
-
// }
-
-
// Console.Write("Press any key to continue . . . ");
-
// Console.ReadKey(true);
-
//}
-
-
/// <summary>
-
/// MIB_IPNETROW structure returned by GetIpNetTable
-
/// DO NOT MODIFY THIS STRUCTURE.
-
/// </summary>
-
[
StructLayout(LayoutKind.Sequential)]
-
struct MIB_IPNETROW
-
{
-
[
MarshalAs(UnmanagedType.U4)]
-
public
int dwIndex;
-
[
MarshalAs(UnmanagedType.U4)]
-
public
int dwPhysAddrLen;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac0;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac1;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac2;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac3;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac4;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac5;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac6;
-
[
MarshalAs(UnmanagedType.U1)]
-
public
byte mac7;
-
[
MarshalAs(UnmanagedType.U4)]
-
public
int dwAddr;
-
[
MarshalAs(UnmanagedType.U4)]
-
public
int dwType;
-
}
-
-
/// <summary>
-
/// GetIpNetTable external method
-
/// </summary>
-
/// <param name="pIpNetTable"></param>
-
/// <param name="pdwSize"></param>
-
/// <param name="bOrder"></param>
-
/// <returns></returns>
-
[
DllImport("IpHlpApi.dll")]
-
[
return: MarshalAs(UnmanagedType.U4)]
-
static extern int GetIpNetTable(IntPtr pIpNetTable,
-
[MarshalAs(UnmanagedType.U4)]
ref
int pdwSize,
bool bOrder);
-
-
/// <summary>
-
/// Error codes GetIpNetTable returns that we recognise
-
/// </summary>
-
const
int ERROR_INSUFFICIENT_BUFFER =
122;
-
/// <summary>
-
/// Get the IP and MAC addresses of all known devices on the LAN
-
/// </summary>
-
/// <remarks>
-
/// 1) This table is not updated often - it can take some human-scale time
-
/// to notice that a device has dropped off the network, or a new device
-
/// has connected.
-
/// 2) This discards non-local devices if they are found - these are multicast
-
/// and can be discarded by IP address range.
-
/// </remarks>
-
/// <returns></returns>
-
private static Dictionary<IPAddress, PhysicalAddress> GetAllDevicesOnLAN()
-
{
-
Dictionary<IPAddress, PhysicalAddress> all =
new Dictionary<IPAddress, PhysicalAddress>();
-
// Add this PC to the list...
-
all.Add(GetIPAddress(), GetMacAddress());
-
int spaceForNetTable =
0;
-
// Get the space needed
-
// We do that by requesting the table, but not giving any space at all.
-
// The return value will tell us how much we actually need.
-
GetIpNetTable(IntPtr.Zero,
ref spaceForNetTable,
false);
-
// Allocate the space
-
// We use a try-finally block to ensure release.
-
IntPtr rawTable = IntPtr.Zero;
-
try
-
{
-
rawTable = Marshal.AllocCoTaskMem(spaceForNetTable);
-
// Get the actual data
-
int errorCode = GetIpNetTable(rawTable,
ref spaceForNetTable,
false);
-
if (errorCode !=
0)
-
{
-
// Failed for some reason - can do no more here.
-
throw
new Exception(
string.Format(
-
"Unable to retrieve network table. Error code {0}", errorCode));
-
}
-
// Get the rows count
-
int rowsCount = Marshal.ReadInt32(rawTable);
-
IntPtr currentBuffer =
new IntPtr(rawTable.ToInt64() + Marshal.SizeOf(
typeof(Int32)));
-
// Convert the raw table to individual entries
-
MIB_IPNETROW[] rows =
new MIB_IPNETROW[rowsCount];
-
for (
int index =
0; index < rowsCount; index++)
-
{
-
rows[index] = (MIB_IPNETROW)Marshal.PtrToStructure(
new IntPtr(currentBuffer.ToInt64() +
-
(index * Marshal.SizeOf(
typeof(MIB_IPNETROW)))
-
),
-
typeof(MIB_IPNETROW));
-
}
-
// Define the dummy entries list (we can discard these)
-
PhysicalAddress virtualMAC =
new PhysicalAddress(
new
byte[] {
0,
0,
0,
0,
0,
0 });
-
PhysicalAddress broadcastMAC =
new PhysicalAddress(
new
byte[] {
255,
255,
255,
255,
255,
255 });
-
foreach (MIB_IPNETROW row
in rows)
-
{
-
IPAddress ip =
new IPAddress(BitConverter.GetBytes(row.dwAddr));
-
byte[] rawMAC =
new
byte[] { row.mac0, row.mac1, row.mac2, row.mac3, row.mac4, row.mac5 };
-
PhysicalAddress pa =
new PhysicalAddress(rawMAC);
-
if (!pa.Equals(virtualMAC) && !pa.Equals(broadcastMAC) && !IsMulticast(ip))
-
{
-
//Console.WriteLine("IP: {0}\t\tMAC: {1}", ip.ToString(), pa.ToString());
-
if (!all.ContainsKey(ip))
-
{
-
all.Add(ip, pa);
-
}
-
}
-
}
-
}
-
finally
-
{
-
// Release the memory.
-
Marshal.FreeCoTaskMem(rawTable);
-
}
-
return all;
-
}
-
-
/// <summary>
-
/// Gets the IP address of the current PC
-
/// </summary>
-
/// <returns></returns>
-
private static IPAddress GetIPAddress()
-
{
-
String strHostName = Dns.GetHostName();
-
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
-
IPAddress[] addr = ipEntry.AddressList;
-
foreach (IPAddress ip
in addr)
-
{
-
if (!ip.IsIPv6LinkLocal)
-
{
-
return (ip);
-
}
-
}
-
return addr.Length >
0 ? addr[
0] :
null;
-
}
-
-
/// <summary>
-
/// Gets the MAC address of the current PC.
-
/// </summary>
-
/// <returns></returns>
-
private static PhysicalAddress GetMacAddress()
-
{
-
foreach (NetworkInterface nic
in NetworkInterface.GetAllNetworkInterfaces())
-
{
-
// Only consider Ethernet network interfaces
-
if (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
-
nic.OperationalStatus == OperationalStatus.Up)
-
{
-
return nic.GetPhysicalAddress();
-
}
-
}
-
return
null;
-
}
-
-
/// <summary>
-
/// Returns true if the specified IP address is a multicast address
-
/// </summary>
-
/// <param name="ip"></param>
-
/// <returns></returns>
-
private static bool IsMulticast(IPAddress ip)
-
{
-
bool result =
true;
-
if (!ip.IsIPv6Multicast)
-
{
-
byte highIP = ip.GetAddressBytes()[
0];
-
if (highIP <
224 || highIP >
239)
-
{
-
result =
false;
-
}
-
}
-
return result;
-
}
-
-
#endregion
-
-
#region MAC扫描方法2
-
-
-
-
static List<
string> ips =
new List<
string>();
-
static Dictionary<
string,
string> dic1 =
new Dictionary<
string,
string>();
-
-
static void GetIPAddress2()
-
{
-
string myHostName = Dns.GetHostName();
//本机名
-
string myHostIP = Dns.GetHostEntry(myHostName).AddressList[
1].ToString();
//本机IP地址
-
string IpRange = myHostIP.Remove(myHostIP.LastIndexOf(
'.'));
//IP网段
-
for (
int r =
1; r <=
255; r++)
//枚举网段计算机
-
{
-
Ping ping =
new Ping();
-
ping.PingCompleted +=
new PingCompletedEventHandler(ping_Completed);
//事件绑定方法
-
string pingIP = IpRange +
"." + r.ToString();
-
ping.SendAsync(pingIP,
1000,
null);
-
}
-
}
-
-
static void ping_Completed(object sender, PingCompletedEventArgs e)
-
{
-
if (e.Reply.Status == IPStatus.Success)
-
{
-
ips.Add(e.Reply.Address.ToString());
-
if (!dic1.ContainsKey(e.Reply.Address.ToString()))
-
{
-
dic1[e.Reply.Address.ToString()] =
"";
-
}
-
}
-
}
-
-
#endregion
-
-
-
-
private void Msg(string e)
-
{
-
try
-
{
-
string msg =
"";
-
//if (string.IsNullOrEmpty(richTextBox1.Text))
-
//{
-
// msg = e;
-
//}
-
//else
-
//{
-
// msg = richTextBox1.Text + "\r\n" + e;
-
//}
-
msg = e;
-
if (
base.InvokeRequired)
-
{
-
base.Invoke(
new MethodInvoker(() =>
-
{
-
richTextBox1.Text = richTextBox1.Text +
"\r\n" + e;
-
}));
-
}
-
else
-
{
-
richTextBox1.Text = richTextBox1.Text +
"\r\n" + e;
-
}
-
}
-
catch
-
{
-
}
-
}
-
-
}
-
}
四、 外网远程唤醒方案
- 家中放一台微型迷你低功耗计算机或者网关(树莓派、网关、迷你服务器)功耗在10W左右,保持24小时常开,一年电费在一百左右。安装向日葵或者ToDesk设置无人值守,支持电脑和手机App连接。随时随地连接到桌面后,用远程发包软件(文中源码或直接下载打包程序)来远程网络唤醒局域网内其他电脑。
- 使用向日葵开机棒,参照官方设置即可,主要是开机棒开放了mac地址开机。可以使得开机棒不局限于一台计算机开机了。在向日葵的网站上找到开机棒,或者在手机就app中找到,然后输入mac地址,即可。
- 使用路由器(例如TP-Link)自带的域名解析功能,参考文章:【超详细】Windows设置远程唤醒WOL+远程连接(远程开机)_wyouzhi@yyds的博客-CSDN博客_远程开机与远程唤醒bios设置
转载:https://blog.csdn.net/hwt0101/article/details/127401108
查看评论