アプリの使い方
最初に作成したアプリの使い方を説明します。
未署名(野良)アプリとなりますが、サイト内からインストーラもダウンロード可能にしています。
※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();
}
}



