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;
}
注意:调用以上方法是需要以管理员身份运行的!!!