Wake on LAN using C#

For the WOL problem you have to clarify three problems to get it to work:

  1. Send a WOL over the ethernet cable
  2. Configure your PC to listen for such a packet and wake up
  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).

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#. 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. 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 (e.g. vpns, etc.).

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.

My goal was to make a universal and easy Wake On Lan class that:

  • works with ipv4, ipv6 and dual-stack.
  • works with one or multiple network cards (NICS) connected to different networks (both computers).
  • works with macaddress in any standard hex format.
  • works using multicast (broadcast is buggy in Windows when using multiple NICs and is not supported when using ipv6).

How to use:

All you need, is the MAC address of the wired nic on the computer you wish to wake up. 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).

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.


I was trying Poul Bak´s answer but was unable to wake my target computer. 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:

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:

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.

Tags:

C#

Wake On Lan