C# 操作Windows系统设备的多种方式
1. WMI(Windows Management Instrumentation)的方式。(网上很多禁用启用设备的方式是.InvokeMethod("Disable", null),只传两个参数,win11上会报错)
常用的一些类库名可以检索 WMI使用的WIN32_类库名WMI使用的WIN32_类库名
// 枚举所有设备 ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from win32_PnPEntity"); foreach (ManagementObject printer in searcher.Get()) { // 设备名称 string name = printer["Name"].ToString(); printer.InvokeMethod("Disable", null, null); printer.InvokeMethod("Enable", null, null); }
2. 使用Windows API。
using System.Runtime.InteropServices; // 打印机信息结构体 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct PRINTER_INFO_2 { [MarshalAs(UnmanagedType.LPWStr)] public string pServerName; [MarshalAs(UnmanagedType.LPWStr)] public string pPrinterName; [MarshalAs(UnmanagedType.LPWStr)] public string pShareName; [MarshalAs(UnmanagedType.LPWStr)] public string pPortName; [MarshalAs(UnmanagedType.LPWStr)] public string pDriverName; [MarshalAs(UnmanagedType.LPWStr)] public string pComment; [MarshalAs(UnmanagedType.LPWStr)] public string pLocation; public IntPtr pDevMode; [MarshalAs(UnmanagedType.LPWStr)] public string pSepFile; [MarshalAs(UnmanagedType.LPWStr)] public string pPrintProcessor; [MarshalAs(UnmanagedType.LPWStr)] public string pDatatype; [MarshalAs(UnmanagedType.LPWStr)] public string pParameters; public IntPtr pSecurityDescriptor; public uint Attributes; public uint Priority; public uint DefaultPriority; public uint StartTime; public uint UntilTime; public uint Status; public uint cJobs; public uint AveragePPM; } // 列举所有打印机设备 [DllImport("winspool.drv", CharSet = CharSet.Unicode, SetLastError = true)] public static extern bool EnumPrinters(uint flags, string name, uint level, IntPtr pPrinterEnum, uint size, ref uint needed, ref uint returned); const uint PRINTER_ENUM_LOCAL = 0x2; const uint PRINTER_ENUM_CONNECTIONS = 0x4; uint needed = 0; uint returned = 0; EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, null, 2, IntPtr.Zero, 0, ref needed, ref returned); IntPtr pPrinterEnum = Marshal.AllocHGlobal((int)needed); bool success = EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, null, 2, pPrinterEnum, needed, ref needed, ref returned); if (success) { IntPtr pCurrentPrinter = pPrinterEnum; for (int i = 0; i < returned; i++) { PRINTER_INFO_2 printer = (PRINTER_INFO_2)Marshal.PtrToStructure(pCurrentPrinter, typeof(PRINTER_INFO_2)); // 打印机名称 string name = printer.pPrinterName; // 打印机状态 string status = printer.Status.ToString(); // ... 其他属性 pCurrentPrinter = new IntPtr(pCurrentPrinter.ToInt64() + Marshal.SizeOf(printer)); } } Marshal.FreeHGlobal(pPrinterEnum);
3. 使用第三方插件,例如devcon。
/// <summary> /// 禁用设备 /// </summary> /// <returns></returns> public async Task<bool> DisableAsync(string id) { string[] cmdDisable = { $"\"{_devConPath}\" disable @\"*{id}\" " }; var disableRes = await StartCmdAsync(cmdDisable); var isSuccess = disableRes.Contains(devDisabled); return isSuccess; }
/// <summary> /// 异步执行Cmd命令并返回结果 /// </summary> /// <param name="commands">执行的CMD命名</param> /// <returns>返回的结果</returns> private async Task<string> StartCmdAsync(params string[] commands) { Process startInfo = new Process(); startInfo.StartInfo.FileName = "cmd.exe"; startInfo.StartInfo.UseShellExecute = false; startInfo.StartInfo.RedirectStandardError = true; startInfo.StartInfo.RedirectStandardInput = true; startInfo.StartInfo.RedirectStandardOutput = true; startInfo.StartInfo.CreateNoWindow = true; startInfo.StartInfo.Verb = "runas"; startInfo.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.Start(); foreach (var cmd in commands) { await startInfo.StandardInput.WriteLineAsync(cmd); } await startInfo.StandardInput.WriteLineAsync("exit"); startInfo.StandardInput.AutoFlush = true; //获取cmd窗口的输出信息 string output = await startInfo.StandardOutput.ReadToEndAsync(); startInfo.Close(); return output; }
注意:调用以上方法是需要以管理员身份运行的!!!