C# Disable/Enable USB ports
Categories:
Mastering USB Port Control in C#: Enable, Disable, and Monitor
Learn how to programmatically enable, disable, and monitor USB ports in C#. This guide covers WMI interactions, device management, and practical code examples for robust control.
Controlling USB ports programmatically in C# can be crucial for security, system administration, or specialized applications. Whether you need to prevent unauthorized data transfer, manage peripheral access, or simply monitor device connections, understanding how to interact with the underlying Windows device management system is key. This article will guide you through the process using Windows Management Instrumentation (WMI) and other relevant APIs.
Understanding USB Device Management in Windows
Windows manages hardware devices, including USB ports, through a complex system involving drivers, device instances, and the Plug and Play (PnP) manager. To programmatically control these devices, we typically interact with WMI, which provides a unified way to query and manage various aspects of the operating system. Disabling a USB port usually involves disabling the associated device instance, which can be a USB host controller, a root hub, or a specific USB device.
flowchart TD A[Start C# Application] --> B{"Identify USB Device"} B --> C{Query WMI for USB Devices} C --> D{Filter for Target Device} D --> E{"Disable/Enable Action"} E --> F{Invoke WMI Method (Disable/Enable)} F --> G[Monitor Status] G --> H[End]
Flowchart of programmatic USB device control in C#
Identifying USB Devices with WMI
The first step in controlling USB ports is to identify the specific devices you want to manage. WMI provides classes like Win32_PnPEntity
and Win32_USBController
that can be queried to list connected USB devices and their properties. We'll primarily use Win32_PnPEntity
as it offers a more comprehensive view of all Plug and Play devices, including their hardware IDs, which are essential for precise targeting.
using System;
using System.Management;
using System.Collections.Generic;
public class UsbDeviceManager
{
public static List<UsbDeviceInfo> GetUsbDevices()
{
List<UsbDeviceInfo> devices = new List<UsbDeviceInfo>();
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE ClassGuid = '{36fc9e60-c465-11cf-8056-444553540000}'"); // USB devices GUID
foreach (ManagementObject queryObj in searcher.Get())
{
devices.Add(new UsbDeviceInfo
{
Name = queryObj["Name"]?.ToString(),
Description = queryObj["Description"]?.ToString(),
DeviceID = queryObj["DeviceID"]?.ToString(),
Status = queryObj["Status"]?.ToString(),
Manufacturer = queryObj["Manufacturer"]?.ToString()
});
}
}
catch (Exception ex)
{
Console.WriteLine("Error getting USB devices: " + ex.Message);
}
return devices;
}
public class UsbDeviceInfo
{
public string Name { get; set; }
public string Description { get; set; }
public string DeviceID { get; set; }
public string Status { get; set; }
public string Manufacturer { get; set; }
}
public static void Main(string[] args)
{
Console.WriteLine("Listing USB Devices:");
foreach (var device in GetUsbDevices())
{
Console.WriteLine($"Name: {device.Name}");
Console.WriteLine($" Description: {device.Description}");
Console.WriteLine($" DeviceID: {device.DeviceID}");
Console.WriteLine($" Status: {device.Status}");
Console.WriteLine($" Manufacturer: {device.Manufacturer}");
Console.WriteLine("----------------------------------");
}
}
}
C# code to list connected USB devices using WMI.
ClassGuid
used in the WMI query ({36fc9e60-c465-11cf-8056-444553540000}
) specifically targets USB devices. You can find other device class GUIDs in the Windows Dev Center documentation if you need to target different device types.Enabling and Disabling USB Devices
Once you have identified the DeviceID
of the target USB device, you can use WMI's Win32_PnPEntity
class to invoke the Disable
or Enable
methods. These methods require administrative privileges to execute successfully. It's important to note that disabling a USB port often means disabling the USB Root Hub or the specific device connected to it. Disabling a root hub will disable all devices connected to that hub.
using System;
using System.Management;
public class UsbPortController
{
public static bool SetUsbDeviceState(string deviceId, bool enable)
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID = '" + deviceId.Replace("\\", "\\") + "'");
foreach (ManagementObject queryObj in searcher.Get())
{
// Check if the device is already in the desired state
if (queryObj["Status"]?.ToString().Equals("OK", StringComparison.OrdinalIgnoreCase) == enable)
{
Console.WriteLine($"Device '{queryObj["Name"]}' is already {(enable ? "enabled" : "disabled")}.");
return true;
}
ManagementBaseObject inParams = null;
ManagementBaseObject outParams = null;
if (enable)
{
inParams = queryObj.GetMethodParameters("Enable");
outParams = queryObj.InvokeMethod("Enable", inParams, null);
}
else
{
inParams = queryObj.GetMethodParameters("Disable");
outParams = queryObj.InvokeMethod("Disable", inParams, null);
}
uint returnValue = (uint)outParams["ReturnValue"];
if (returnValue == 0) // 0 indicates success
{
Console.WriteLine($"Successfully {(enable ? "enabled" : "disabled")} device: {queryObj["Name"]}");
return true;
}
else
{
Console.WriteLine($"Failed to {(enable ? "enable" : "disable")} device: {queryObj["Name"]}. Return value: {returnValue}");
return false;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error setting USB device state: " + ex.Message);
}
return false;
}
public static void Main(string[] args)
{
// Example Usage:
// 1. Find the DeviceID of the USB device you want to control
// (e.g., from the output of GetUsbDevices() or Device Manager)
string targetDeviceId = "USB\\VID_046D&PID_C077\\5&295A2B0&0&1"; // Replace with your target DeviceID
Console.WriteLine($"Attempting to disable device: {targetDeviceId}");
SetUsbDeviceState(targetDeviceId, false); // Disable the device
Console.WriteLine("\nWaiting 5 seconds...");
System.Threading.Thread.Sleep(5000);
Console.WriteLine($"\nAttempting to enable device: {targetDeviceId}");
SetUsbDeviceState(targetDeviceId, true); // Enable the device
}
}
C# code to enable or disable a specific USB device by its DeviceID.
Enable
or Disable
will likely fail with an access denied error. Also, be cautious when disabling devices, as you might inadvertently disable critical system components like your keyboard or mouse if they are USB-connected.Monitoring USB Device Connections
Beyond enabling and disabling, you might want to monitor when USB devices are connected or disconnected. WMI provides event queries that allow your application to subscribe to system events, such as device arrival or removal. This is achieved using ManagementEventWatcher
.
using System;
using System.Management;
public class UsbMonitor
{
public static void StartMonitoring()
{
// WQL query for device arrival events
WqlEventQuery arrivalQuery = new WqlEventQuery(
"SELECT * FROM __InstanceCreationEvent WITHIN 2 " +
"WHERE TargetInstance ISA 'Win32_PnPEntity' AND TargetInstance.ClassGuid = '{36fc9e60-c465-11cf-8056-444553540000}'");
ManagementEventWatcher arrivalWatcher = new ManagementEventWatcher(arrivalQuery);
arrivalWatcher.EventArrived += new EventArrivedEventHandler(DeviceArrived);
arrivalWatcher.Start();
Console.WriteLine("Monitoring for USB device arrivals... Press any key to stop.");
// WQL query for device removal events
WqlEventQuery removalQuery = new WqlEventQuery(
"SELECT * FROM __InstanceDeletionEvent WITHIN 2 " +
"WHERE TargetInstance ISA 'Win32_PnPEntity' AND TargetInstance.ClassGuid = '{36fc9e60-c465-11cf-8056-444553540000}'");
ManagementEventWatcher removalWatcher = new ManagementEventWatcher(removalQuery);
removalWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemoved);
removalWatcher.Start();
Console.ReadKey();
arrivalWatcher.Stop();
removalWatcher.Stop();
Console.WriteLine("Monitoring stopped.");
}
private static void DeviceArrived(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
Console.WriteLine($"\nUSB Device Arrived:");
Console.WriteLine($" Name: {instance["Name"]}");
Console.WriteLine($" DeviceID: {instance["DeviceID"]}");
Console.WriteLine($" Description: {instance["Description"]}");
}
private static void DeviceRemoved(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
Console.WriteLine($"\nUSB Device Removed:");
Console.WriteLine($" Name: {instance["Name"]}");
Console.WriteLine($" DeviceID: {instance["DeviceID"]}");
Console.WriteLine($" Description: {instance["Description"]}");
}
public static void Main(string[] args)
{
StartMonitoring();
}
}
C# code to monitor USB device arrival and removal events.
WITHIN 2
clause in the WQL query specifies the polling interval in seconds. This means WMI will check for new events every 2 seconds. Adjust this value based on your application's responsiveness requirements versus system resource usage.