简体   繁体   English

使用 C# 在 LAN 上唤醒

[英]Wake on LAN using C#

What's the best way going forward to implement Wake on LAN using C#?使用 C# 实现局域网唤醒的最佳方式是什么?

The functionality is needed for machines in a LAN environment (and not over the inte.net). LAN 环境中的机器需要该功能(而不是通过 inte.net)。 The method needs to be robust enough to take care of firewalls and other such issues.该方法需要足够健壮以应对防火墙和其他此类问题。 Also, for systems not supporting this functionality, or having it disabled, is there an alternative?此外,对于不支持或禁用此功能的系统,是否有替代方案?

The primary objective - wake up machines (from shutdown/hibernate state) over the LAN - this is to be programmed using C#.主要目标 - 通过 LAN 唤醒机器(从关机/休眠状态) - 这将使用 C# 进行编程。

Please guide.请指导。

PS: I've come across the following: PS:我遇到过以下情况:

  1. http://blog.memos.cz/index.php/team/2008/06/12/wake-on-lan-in-csharp http://blog.memos.cz/index.php/team/2008/06/12/wake-on-lan-in-csharp
  2. http://community.bartdesmet.net/blogs/bart/archive/2006/04/02/3858.aspx http://community.bartdesmet.net/blogs/bart/archive/2006/04/02/3858.aspx
  3. http://www.codeproject.com/KB/IP/cswol.aspx http://www.codeproject.com/KB/IP/cswol.aspx

However, I'm new to this and hence couldn't figure if the solutions were comprehensive enough.但是,我对此并不陌生,因此无法确定解决方案是否足够全面。 If someone could recommend following either of the above articles, that'd help.如果有人可以推荐阅读上述任何一篇文章,那将会有所帮助。

For the WOL problem you have to clarify three problems to get it to work:对于 WOL 问题,您必须澄清三个问题才能使其发挥作用:

  1. Send a WOL over the ethernet cable通过以太网电缆发送 WOL
  2. Configure your PC to listen for such a packet and wake up配置您的 PC 以侦听此类数据包并唤醒
  3. Make sure the packet will come from sender to receiver (firewall, gateways, etc.)确保数据包将来自发送方到接收方(防火墙、网关等)

As you already found on the net there are existing several solutions for the first problem programmed in C# (and after skimming your links, I would start with the first one).正如您已经在网上发现的,对于用 C# 编程的第一个问题,存在多种解决方案(浏览您的链接后,我将从第一个开始)。

The second one is something you can only achieve by configuring your network adapter.第二个是您只能通过配置网络适配器来实现的。 Just open the device manager and take a look into the properties of your network adapter, if such an option exists and if you can enable it.只需打开设备管理器并查看网络适配器的属性,如果存在此类选项并且您可以启用它。 This can't be programmed, due to the fact that every network adapter has another implementation of that function and how it can be enabled.这无法编程,因为每个网络适配器都有该功能的另一种实现以及如何启用它。

The third problem can't also be solved by C#.第三个问题也不能用C#解决。 It is a pure network problem, where you have to configure your router, gateways, ids-systems, etc. to allow such a packet and let it flow from sender to receiver.这是一个纯粹的网络问题,你必须配置你的路由器、网关、ids-systems 等,以允许这样的数据包并让它从发送者流向接收者。 Due to the fact, that a WOL packet is always a broadcast packet (dest-ip 255.255.255.255) it won't leave your local network and will always be dropped from router, gateways or any other bridge between to networks (eg vpns, etc.).由于 WOL 数据包始终是广播数据包 (dest-ip 255.255.255.255),它不会离开您的本地网络,并且始终会从路由器、网关或网络之间的任何其他桥接器(例如 vpns、等等。)。

Last but not least, I will just remind you, that the first problem can be divided into some smaller packets but as far as I could see these problems are all capped by the links you provided.最后但并非最不重要的一点是,我会提醒您,第一个问题可以分为一些较小的数据包,但据我所知,这些问题都受到您提供的链接的限制。

Very old question, I know, but still valid.很老的问题,我知道,但仍然有效。 Since I didn't see any C# in the accepted answer, I wrote my own 'Wake On Lan' code.由于我在接受的答案中没有看到任何 C#,因此我编写了自己的“Wake On Lan”代码。

My goal was to make a universal and easy Wake On Lan class that:我的目标是制作一个通用且简单的Wake On Lan class

  • works with ipv4 , ipv6 and dual-stack .适用于ipv4ipv6dual-stack
  • works with one or multiple network cards (NICS) connected to different networks (both computers).适用于连接到不同网络(两台计算机)的一个或多个网卡(NICS)。
  • works with macaddress in any standard hex format.适用于任何标准十六进制格式的macaddress
  • works using multicast (broadcast is buggy in Windows when using multiple NICs and is not supported when using ipv6).使用多播工作(使用多个 NIC 时,Windows 中的广播有问题,使用 ipv6 时不受支持)。

How to use:如何使用:

All you need, is the MAC address of the wired nic on the computer you wish to wake up.您所需要的只是您要唤醒的计算机上有线网卡的MAC 地址 Any standard hex representation will do.任何标准的十六进制表示都可以。 Then call the code like this:然后像这样调用代码:

string mac = "01-02-03-04-05-06";
await WOL.WakeOnLan(mac);

Here's the class:这是课程:

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

public static class WOL
{

    public static async Task WakeOnLan(string macAddress)
    {
        byte[] magicPacket = BuildMagicPacket(macAddress);
        foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces().Where((n) =>
            n.NetworkInterfaceType != NetworkInterfaceType.Loopback && n.OperationalStatus == OperationalStatus.Up))
        {
            IPInterfaceProperties iPInterfaceProperties = networkInterface.GetIPProperties();
            foreach (MulticastIPAddressInformation multicastIPAddressInformation in iPInterfaceProperties.MulticastAddresses)
            {
                IPAddress multicastIpAddress = multicastIPAddressInformation.Address;
                if (multicastIpAddress.ToString().StartsWith("ff02::1%", StringComparison.OrdinalIgnoreCase)) // Ipv6: All hosts on LAN (with zone index)
                {
                    UnicastIPAddressInformation unicastIPAddressInformation = iPInterfaceProperties.UnicastAddresses.Where((u) =>
                        u.Address.AddressFamily == AddressFamily.InterNetworkV6 && !u.Address.IsIPv6LinkLocal).FirstOrDefault();
                    if (unicastIPAddressInformation != null)
                    {
                        await SendWakeOnLan(unicastIPAddressInformation.Address, multicastIpAddress, magicPacket);
                        break;
                    }
                }
                else if (multicastIpAddress.ToString().Equals("224.0.0.1")) // Ipv4: All hosts on LAN
                {
                    UnicastIPAddressInformation unicastIPAddressInformation = iPInterfaceProperties.UnicastAddresses.Where((u) =>
                        u.Address.AddressFamily == AddressFamily.InterNetwork && !iPInterfaceProperties.GetIPv4Properties().IsAutomaticPrivateAddressingActive).FirstOrDefault();
                    if (unicastIPAddressInformation != null)
                    {
                        await SendWakeOnLan(unicastIPAddressInformation.Address, multicastIpAddress, magicPacket);
                        break;
                    }
                }
            }
        }
    }

    static byte[] BuildMagicPacket(string macAddress) // MacAddress in any standard HEX format
    {
        macAddress = Regex.Replace(macAddress, "[: -]", "");
        byte[] macBytes = new byte[6];
        for (int i = 0; i < 6; i++)
        {
            macBytes[i] = Convert.ToByte(macAddress.Substring(i * 2, 2), 16);
        }

        using (MemoryStream ms = new MemoryStream())
        {
            using (BinaryWriter bw = new BinaryWriter(ms))
            {
                for (int i = 0; i < 6; i++)  //First 6 times 0xff
                {
                    bw.Write((byte)0xff);
                }
                for (int i = 0; i < 16; i++) // then 16 times MacAddress
                {
                    bw.Write(macBytes);
                }
            }
            return ms.ToArray(); // 102 bytes magic packet
        }
    }

    static async Task SendWakeOnLan(IPAddress localIpAddress, IPAddress multicastIpAddress, byte[] magicPacket)
    {
        using (UdpClient client = new UdpClient(new IPEndPoint(localIpAddress, 0)))
        {
            await client.SendAsync(magicPacket, magicPacket.Length, multicastIpAddress.ToString(), 9);
        }
    }
}

How it works:这个怎么运作:

The code works by enumerating all network cards that are 'up' and connected to your network (that's usually just one).该代码的工作原理是枚举所有“启动”并连接到您的网络的网卡(通常只有一张)。 It will send out the 'magic packet' to all your connected networks using multicast, which works with both ipv4 and ipv6 (don't worry about flooding your network, it's only 102 bytes).它将使用多播向所有连接的网络发送“魔法数据包”,该多播适用于 ipv4 和 ipv6(不要担心网络泛滥,它只有 102 字节)。

To work, the computer, you want to wake up, must have a wired connection (wireless computers can't be woken up, since they aren't connected to any network, when they are off).为了工作,你想唤醒的计算机必须有有线连接(无线计算机不能被唤醒,因为它们没有连接到任何网络,当它们关闭时)。 The computer, that sends the packet, can be wireless connected.发送数据包的计算机可以无线连接。

Firewalls are usually no problem, since the computer is off and hence the firewall is not active.防火墙通常没有问题,因为计算机已关闭,因此防火墙未处于活动状态。

You must make sure that 'Wake on lan' is enabled in the computer's BIOS and on the network card.您必须确保在计算机的BIOS和网卡上enabled了“ 'Wake on lan'

I was trying Poul Bak´s answer but was unable to wake my target computer.我正在尝试 Poul Bak 的回答,但无法唤醒我的目标计算机。 After verifying that a third party application, WakeMeOnLan in fact was able to wake my target computer, I wrote this code that worked for me:在验证第三方应用程序WakeMeOnLan实际上能够唤醒我的目标计算机后,我编写了以下对我有用的代码:

void SendWakeOnLan(PhysicalAddress target)
{   
    var header = Enumerable.Repeat(byte.MaxValue, 6);
    var data = Enumerable.Repeat(target.GetAddressBytes(), 16).SelectMany(mac => mac);

    var magicPacket = header.Concat(data).ToArray();
    
    using var client = new UdpClient();

    client.Send(magicPacket, magicPacket.Length, new IPEndPoint(IPAddress.Broadcast, 9));
}

Usage:用法:

Simply by passing in the target computers mac address like so:只需传入目标计算机的 mac 地址,如下所示:

SendWakeOnLan(PhysicalAddress.Parse("0A-0B-0C-0D-0E-0F"));

I think the main difference between this answer and Poul Bak´s answer is that this code is using broadcast over IPv4 instead of multicast on IPv4/IPv6, and maybe my network equipment is not handling/setup to do multicast correctly.我认为此答案与 Poul Bak 的答案之间的主要区别在于,此代码使用 IPv4 上的广播而不是 IPv4/IPv6 上的多播,而且我的网络设备可能未正确处理/设置以进行多播。

Should it work even connected by VPN outside the local.network?即使通过 local.network 之外的 VPN 连接它也应该工作吗? It is that from the same.network it works for me, but not from outside.这是来自 same.network 它对我有用,但不是来自外部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM