アプリの使い方
最初に作成したアプリの使い方を説明します。
未署名(野良)アプリとなりますが、サイト内からインストーラもダウンロード可能にしています。
※Windows10以降では危険なアプリとして認識されます。
MACアドレスの取得
Wake on lanしたいPCが起動した状態で、PCに割り当てられたIPアドレスを指定して、MACアドレスを取得しておきます。
この作業は一度行えば、アプリケーション内にMACアドレスが保存されます。
MagicPacketの送信
起動したいPCの電源が切れた状態で、PortとAreaを設定し、"SendMP"ボタンを押すとマジックパケットを送信します。
MACアドレスの取得
Wake on lanはブロードキャストアドレスに対して、NICのMACアドレスを含むパケットを送信します。
そのためにはMACアドレスを取得する機能が必要なので実装しておきます。
Send ARP機能
まずはWake on lanしたいPCを起動した状態で、IPアドレスを指定し、MACアドレスを取得する機能の実装です。
自作でMacAddressクラスを作成しました。
[DllImport("iphlpapi.dll", ExactSpelling = true)] private static extern int SendARP(int DestIP, int SrcIp, byte[] pMacAddr, ref int PhyAddrLen); public byte[] macAddr; public int macAddrLen; public IPAddress ipAddress; public MacAddress() { macAddr = new byte[6]; macAddrLen = macAddr.Length; } public bool SetIpAddr(string ipAddrStr) { if (IPAddress.TryParse(ipAddrStr, out ipAddress)) { return true; } else { return false; } } public bool TrySendArp() { int addr = BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0); //IPv4値を値に変換 int ret = SendARP(addr, 0, macAddr, ref macAddrLen); if (ret == 0) { return true; } else { return false; } } }
クラスの使用方法は"SetIpAddr"メソッドでIPアドレスを設定し、"TrySendArp"メソッドを実行することでMACアドレスが取得できます。
取得したMACアドレスはbyte配列で取得できます。以下、コード例です。
ボタンクリックイベントでテキストボックスからIPアドレスの文字列データを取得し、MACアドレスを取得します。
取得したMACアドレスをテキストボックスに表示するとともに、ユーザーデータとして保存しています。
private void BtnSendArp_Click(object sender, EventArgs e) { MacAddress macAddress = new MacAddress(); if (macAddress.SetIpAddr(TbxIpAddress.Text)) { if (macAddress.TrySendArp()) { TbxMacAddress.Text = BitConverter.ToString(macAddress.macAddr); Properties.Settings.Default.MacAddress = TbxMacAddress.Text; Properties.Settings.Default.Save(); } } }
事前にMACアドレスを取得しておく
別の方法でMACアドレスが取得できればSend ARP機能は不要ですが、実用的なアプリを作りたかったので、MACアドレス取得機能を実装しました。
実際に使用する場合はWake on lanしたいPCが起動した状態でMACアドレスを取得しておき、ユーザーデータとして保存しておくことで、マジックパケット送信時に使用できます。
マジックパケットの送信
次にマジックパケット送信機能の実装です。
以前作成したUdpClientクラスも流用します。
MagicPacketクラス
UdpClientを使用して任意のネットワークにマジックパケットを送信する機能を持つクラスです。
プロパティの"ipaddress"にはブロードキャストアドレスを登録して、使用します。
internal class MagicPacket { public byte[] macAddress; public byte[] broadcastPacket; public IPAddress ipaddress; public TcpUdpCommunication.UdpClient udpClient; public MagicPacket(MacAddress macAddr) { macAddress = macAddr.macAddr; } public MagicPacket(byte[] macAddr) { macAddress = macAddr; } public MagicPacket() { } public bool SetMacAddress(string macAddrStr) { try { PhysicalAddress physicalAddress = PhysicalAddress.Parse(macAddrStr); macAddress = physicalAddress.GetAddressBytes(); return true; } catch { return false; } } public void UdpClientInit(string ipAddrStr, int port) { if (IPAddress.TryParse(ipAddrStr, out IPAddress ipAddress)) { } else { } udpClient = new TcpUdpCommunication.UdpClient(ipAddress, port); } public void SendPacket() { udpClient.sendData = SetPacket(); udpClient.ComTaskGen(); } private byte[] SetPacket() { byte[] packet = new byte[6 + 6 * 16]; Array.Copy(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 0, packet, 0, 6); for (int i = 1; i <= 16; ++i) Array.Copy(macAddress, 0, packet, i * macAddress.Length, macAddress.Length); return packet; } }
使用例
まず、"SetMacAddress"メソッドでMACアドレスを登録します。引数として与えるMACアドレスは文字列形式です。
そして、"UdpClientInit"メソッドブロードキャストアドレスとポート番号を与えて準備完了です。
"SendPacket"メソッドを実行するとマジックパケットを送信します。
private void BtnSendMagicPacket_Click(object sender, EventArgs e) { MagicPacket magicPacket = new MagicPacket(); magicPacket.SetMacAddress(TbxMacAddress.Text); if(Int32.TryParse(TbxPort.Text, out int intBuf)) { magicPacket.UdpClientInit(TbxAreaAddress.Text, intBuf); magicPacket.SendPacket(); } }