📅  最后修改于: 2023-12-03 15:41:55.878000             🧑  作者: Mango
有时候我们需要在连接 USB 设备时自动打开文件资源管理器,以方便我们进行文件的查看和操作。在 Windows 操作系统中,我们可以使用 C# 编写程序实现该功能。
using System.Management;
ManagementEventWatcher watcher = new ManagementEventWatcher();
WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); // EventType 2 表示插入事件
watcher.EventArrived += new EventArrivedEventHandler(USBInserted);
watcher.Query = query;
watcher.Start();
public static void USBInserted(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
if (instance.Properties["InterfaceType"].Value.ToString() == "USB") // 判断是否为 USB 设备
{
string driveLetter = instance.Properties["Name"].Value.ToString().Substring(0, 2); // 获取 USB 设备的盘符
string path = driveLetter + @"\";
System.Diagnostics.Process.Start("explorer.exe", path); // 打开文件资源管理器并跳转到 USB 设备的根目录
}
}
watcher.Stop();
using System.Runtime.InteropServices;
using Microsoft.Win32;
const int WM_DEVICECHANGE = 0x219; // 设备状态改变消息
const int DBT_DEVICEARRIVAL = 0x8000; // 设备插入消息
const int DBT_DEVTYP_VOLUME = 0x00000002; // 逻辑卷设备
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_DEVICECHANGE)
{
int wParam = m.WParam.ToInt32();
if (wParam == DBT_DEVICEARRIVAL) // 设备插入
{
DEV_BROADCAST_VOLUME vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
if (vol.dbcv_devicetype == DBT_DEVTYP_VOLUME) // 逻辑卷设备
{
string driveLetter = GetDriveLetter(vol.dbcv_unitmask);
string path = driveLetter + @"\";
System.Diagnostics.Process.Start("explorer.exe", path); // 打开文件资源管理器并跳转到 USB 设备的根目录
}
}
}
}
private string GetDriveLetter(int mask)
{
char[] drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
for (int i = 0; i < 26; i++)
{
int bit = 1 << i;
if ((mask & bit) != 0)
{
string drive = drives[i].ToString();
return drive + ":";
}
}
return "";
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
RegisterUSBEvent();
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
UnregisterUSBEvent();
}
private void RegisterUSBEvent()
{
DEV_BROADCAST_DEVICEINTERFACE dbi = new DEV_BROADCAST_DEVICEINTERFACE();
dbi.dbcc_size = Marshal.SizeOf(dbi);
dbi.dbcc_devicetype = 5; // DBT_DEVTYP_DEVICEINTERFACE
dbi.dbcc_reserved = 0;
dbi.dbcc_classguid = new Guid("{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"); // GUID_DEVINTERFACE_VOLUME
IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(dbi));
Marshal.StructureToPtr(dbi, buffer, true);
IntPtr hwnd = this.Handle;
uint flags = 0;
IntPtr hDevNotify = RegisterDeviceNotification(hwnd, buffer, flags);
}
private void UnregisterUSBEvent()
{
DEV_BROADCAST_DEVICEINTERFACE dbi = new DEV_BROADCAST_DEVICEINTERFACE();
dbi.dbcc_size = Marshal.SizeOf(dbi);
dbi.dbcc_devicetype = 5; // DBT_DEVTYP_DEVICEINTERFACE
dbi.dbcc_reserved = 0;
dbi.dbcc_classguid = new Guid("{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"); // GUID_DEVINTERFACE_VOLUME
IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(dbi));
Marshal.StructureToPtr(dbi, buffer, true);
IntPtr hwnd = this.Handle;
uint flags = 0;
UnregisterDeviceNotification(hDevNotify);
}
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
public Guid dbcc_classguid;
public char dbcc_name;
}
[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_VOLUME
{
public int dbcv_size;
public int dbcv_devicetype;
public int dbcv_reserved;
public int dbcv_unitmask;
public char dbcv_flags;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, uint Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool UnregisterDeviceNotification(IntPtr Handle);
以上是两种方法实现连接 USB 设备时自动打开文件资源管理器的代码片段,可以根据实际需要选择其中的一种方法进行使用。