How To Find Specific USB Devices That Are Connected

This example works by looking for a specific USB device VID and PID and was made to work with devices using Microchips USB CDC USB firmware stack.  However it will work with all sorts of USB devices.


	using namespace System::IO::Ports;		//< Needed for USB serial port
	using namespace Microsoft::Win32;		//< Needed to access registry

	int Count;
	int CharPosn;
	int CheckEachPortCount;
	String ^RegistryMainFolder;
	String ^Port;
	array<String^> ^Names;
	String ^Name;
	array<String^> ^FoundCommPorts = gcnew array<String^>(0);


	//----- FIND OUR USB SERIAL PORT DEVICE -----
	try
	{
		//----- DISCOVER ALL AVAILABLE SERIAL PORTS -----
		array<String^> ^AvailableSerialPorts;
		 AvailableSerialPorts = SerialPort::GetPortNames();

		//>>>>>>>>>>>>>>>> DEBUG SIMULATE COM PORT CONNECTED
		//Array::Resize(AvailableSerialPorts, AvailableSerialPorts->Length + 1);
		//AvailableSerialPorts[AvailableSerialPorts->Length - 1] = "COM3";
		//<<<<<<<<<<<<<<<<<<<

		//----- CHECK REGISTRY TO FIND MATCHING USB DEVICES AND ONLY INCLUDE THOSE COMM PORTS -----
		//(We only show comm ports for our devices that are currently connected)
		//This is the registry path we're interested
		//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\[VID_VID+PID_PID]\[RandomName]\DeviceParameters\PortName

		//Retrieve all the subkeys for the specified key.
		RegistryMainFolder= L"SYSTEM\\CurrentControlSet\\Enum\\USB";
		RegistryKey ^rkey = Registry::LocalMachine;
		rkey = rkey->OpenSubKey(RegistryMainFolder);
		Names = rkey->GetSubKeyNames();

		for each (Name in Names)
		{
			//----- CHECK NEXT USB DEVICE IN THE REGISTRY -----
			//This example is based on finding only devices where the USB name includes a specific VID and PID value like this:
			//name = VID_04D8&PID_F677

			if (
				(Name->Contains("VID_04D8")) &&		//<<<<<<< OUR VID VALUE OUR USB DEVICE NAME WILL CONTAIN
				(Name->Contains("PID_F677"))		//<<<<<<< OUR PID VALUE OUR USB DEVICE NAME WILL CONTAIN
			)
			{
				//----- THIS REGISTRY ENTRY LISTS ALL USB DEVICES WITH OUR VID AND PID -----
				RegistryKey ^rkey2 = Registry::LocalMachine;
				rkey2 = rkey2->OpenSubKey(RegistryMainFolder);
				rkey2 = rkey2->OpenSubKey(Name);
				Names = rkey2->GetSubKeyNames();
				for each (Name in Names)
				{
					//----- GET NEXT USB DEVICE ENTRY -----
					try
					{
						RegistryKey ^rkey3 = Registry::LocalMachine;
						rkey3 = rkey2->OpenSubKey(Name + L"\\Device Parameters");
						Port = Convert::ToString(rkey3->GetValue("PortName"));			//Will be "COM1" etc

						//IS THIS USB DEVICE CURRENTLY CONNECTED?
						for (CheckEachPortCount = 0; CheckEachPortCount < AvailableSerialPorts->Length; CheckEachPortCount++)
						{
							if (AvailableSerialPorts[CheckEachPortCount]->ToString() == Port->ToString())
							{
								//THIS PORT EXISTS SO DEVICE IS CONNECTED - ADD IT TO THE ARRAY OF FOUND DEVICES
								Array::Resize(FoundCommPorts, FoundCommPorts->Length + 1);
								FoundCommPorts[FoundCommPorts->Length - 1] = Port;
								break;
							}
						}
						rkey3->Close();
					}
					catch(System::Exception ^)
					{
					}						
				}
				rkey2->Close();
			}
		}
		rkey->Close();

		//ADD EACH OF THE FOUND DEVICES TO THE COMM PORT COMBO BOX
		if (FoundCommPorts->Length)
		{
			Array::Sort(FoundCommPorts);		//Sort by port number

			for (Count = 0; Count < FoundCommPorts->Length; Count++)
			{
				cmbCommPort->Items->Add(FoundCommPorts[Count]);
			}

		}
	}
	catch(System::Exception^ e)
	{
		//MessageBox::Show(L"Error looking for USB device:\n" + e, L"Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
	}

 

 

 

 

Feel free to comment if you can add help to this page or point out issues and solutions you have found. I do not provide support on this site, if you need help with a problem head over to stack overflow.

Comments

Your email address will not be published.