在Unity中使用局域网远程操控电脑
通过局域网实现由一台设备控制其它其它设备黑屏与开关机。
一、黑屏肃静
1、调用Windows底层库控制黑屏
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool PostMessage(int hWnd, int wMsg, int wParam, int lParam);
const int HWND_BROADCAST = 0xFFFF;
const int WM_SYSCOMMAND = 0x0112;
const int SC_MONITORPOWER = 0xF170;
黑屏
PostMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
取消黑屏
PostMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
2、模拟操作
结果测试,单靠PostMessage无法解锁黑屏,所以还需要模拟鼠标点击来解锁。
引入库:
private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, IntPtr dwExtraInfo);//模拟鼠标点击
[DllImport("user32.dll", CharSet = CharSet.Auto)]
调用:
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, IntPtr.Zero); //模拟鼠标点击,唤醒屏幕
3、禁用键鼠
通过键鼠可以解锁黑屏,所以需要禁用键鼠。
键鼠开关库:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void BlockInput(bool fBlockIt);
4、轮询黑屏
结果测试,虽然禁用了键鼠,但还是可能会被键盘操作或调任务管理器的操作解锁黑屏。所以要彻底解决这个问题,就需要每个一段时间发送一次黑屏命令。
二、开关机
1、关机
关机比较简单,通过调Windows的关机命令就可以实现。
Process.Start("shutdown", "/s /t 0");
2、开机
1) 启用目标计算机的 WOL 功能
首先,确保目标计算机的网卡和 BIOS 都支持并启用了 Wake-on-LAN 功能。具体步骤如下:
● BIOS 设置:进入 BIOS 并启用 WOL 功能,一般在电源管理或网络选项中。
● 操作系统设置:在 Windows 上启用网络适配器的 WOL 功能:进入“设备管理器”,找到网卡,右键选择“属性”,在“电源管理”选项卡下,确保选中“允许此设备唤醒计算机”。
2)发送 WOL 数据包
WOL 依赖于向目标设备的 MAC 地址发送特定格式的“魔术包”(Magic Packet)。Unity 本身不提供直接的 WOL 支持,但可以通过 C# 来发送该数据包。
using System;
using System.Net;
using System.Net.Sockets;
public class WakeOnLan
{
public static void SendMagicPacket(string macAddress)
{
UdpClient client = new UdpClient();
client.EnableBroadcast = true;
// 将 MAC 地址转换为字节数组
byte[] macBytes = ParseMacAddress(macAddress);
// 构造魔术包:6字节的FF + 16次MAC地址
byte[] magicPacket = new byte[102];
for (int i = 0; i < 6; i++)
{
magicPacket[i] = 0xFF;
}
for (int i = 1; i <= 16; i++)
{
Array.Copy(macBytes, 0, magicPacket, i * 6, 6);
}
// 发送魔术包
client.Send(magicPacket, magicPacket.Length, new IPEndPoint(IPAddress.Broadcast, 9));
client.Close();
}
private static byte[] ParseMacAddress(string macAddress)
{
byte[] macBytes = new byte[6];
string[] macParts = macAddress.Split(':');
for (int i = 0; i < 6; i++)
{
macBytes[i] = Convert.ToByte(macParts[i], 16);
}
return macBytes;
}
}