C# 实现远程开关指定主机

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/msst1234/article/details/79567728

 

一、远程开机

远程唤起(Wake on LAN)是AMD公司制作的MagicPacket这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(MagicPacket)。魔术包的格式,包含有连续6个字节的“FF”和连续重复16次的MAC地址,你可以在任何协议的数据包中填上 "FFFFFFFFFFFF"+连续重复16次的MAC地址,就可利用该协议作出一个使用该协议的MagicPacket来实现C#版的工具。

 

第一步:

远程开机需要进入需要唤起的BIOS模式下将“Wake upon LAN”项或“Wake on PCI Card”项均设置为“Enable”,其原理就是通过广播消息发送UDP包到指定的主机的网卡,通过网卡唤起主机。

 

第二步:

 借助上述描述的魔术包编写一个工具类,具体如下:

using System;

usingSystem.Net;

usingSystem.Net.Sockets;

 

namespaceTool.WakeOnLan

{

   ///<summary>

   ///使用网络启动指定计算机

   ///</summary>

   publicstaticclassWakeOnLanHelper

   {

       ///<summary>

       ///启动指定物理地址的计算机,此计算机必须开启网络启动的设置

       ///</summary>

       ///<param name="mac">物理地址数组</param>

       publicstaticvoid WakeUp(byte[] mac)

       {

            try

            {

                UdpClient client = newUdpClient();

                client.Connect(IPAddress.Broadcast, 9090);

 

                byte[] packet = newbyte[17 * 6];

 

                //写入6字节FF

                for (int i = 0; i < 6; i++)

                    packet[i] = 0xFF;

                //写入16遍mac地址

                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);

            }

            catch (Exception ex)

            {

                //Logger.Log.Debug("网络唤起指定计算机异常" + ex.ToString());

            }

       }

 

       ///<summary>

       ///启动指定物理地址的计算机,此计算机必须开启网络启动的设置

       ///</summary>

       ///<param name="mac">物理地址 FF-FF-FF-FF-FF-FF格式</param>

       publicstaticvoid WakeUp(string macString)

       {

            try

            {

                if (null != macString && macString.Split('-').Length == 6)

                {

                    string[] macStringArray = macString.Split('-');

                    byte[] macByteArray = newbyte[6];

                    for (int i = 0; i < 6; i++)

                    {

                        macByteArray[i] = Convert.ToByte(macStringArray[i],16);

                    }

 

                    UdpClient client = newUdpClient();

                    client.Connect(IPAddress.Broadcast, 9090);

 

                    byte[] packet = newbyte[17 * 6];

 

                    //写入6字节FF

                    for (int i = 0; i < 6; i++)

                        packet[i] = 0xFF;

                    //写入16遍mac地址

                    for (int i = 1; i <= 16; i++)

                        for (int j = 0; j < 6;j++)

                            packet[i * 6 + j] =macByteArray[j];

 

                    int result = client.Send(packet, packet.Length);

                }

            }

            catch (Exception ex)

            {

               // Logger.Log.Debug("网络唤起指定计算机异常"+ex.ToString());

            }

 

         

       }

   }

}

 

 

调用工具类的WakeUp函数就可远程唤起指定计算机。

 

 

二、远程关机

 首先我们可以参考shutdown命令

 

其中-m --computer可以远程关闭指定目标计算机,而在我的项目中使用C/S模式,所以可以使用数据包发送命令来让客户端关机。

所以当客户端收到关机命令后使用shutdown -s -t  XX来关闭, XX指的是延迟时间。

但是在测试过程中,使用shutdown -s -t  XX关机后,就无法再次远程唤起。经过研究需要增加-hybrid的参数,即可再次远程开机,具体C#代码:

System.Diagnostics.Process.Start("cmd.exe", "/cshutdown -s -t 0 -hybrid")

含义:

此处花费了不少时间研究再次远程唤起,所以写个帖子供需要的参考。

 

 

此外异常关机(断电、强行关机)等都会影响远程开机无法正常执行。

-----------------------------------------分割线----------------------

 附:在DELL的一个机子上的版本发现设置网络唤起的设置比较个性,参考链接

https://www.dell.com/support/article/cn/zh/cndhs1/sln305365/%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E6%82%A8%E7%9A%84%E6%88%B4%E5%B0%94%E7%B3%BB%E7%BB%9F%E4%B8%8A%E9%80%9A%E8%BF%87lan%E5%94%A4%E9%86%92-wol-?lang=zh

另外关机的时候发现在dell的win10家庭版的关机语句增加-hybrid 参数到无法再次网络唤起,删除-hybrid后可以正常再次网络唤起。

 

参考文章:

https://www.cnblogs.com/DHUtoBUAA/p/5440441.html  感谢

展开阅读全文

没有更多推荐了,返回首页