1
Vote

Multiple USB Printers using same port

description

Below is an updated version of the EnumDevices function for the latest patch. It enables the use of multiple usb printers attached to the same port.

I switched the string and int values of the printerNames. I also validate that the registry key has a "Port" value. I noticed that the function would break if a printer like Microsoft XPS Viewer (which has no port) was encountered.
public static Dictionary<string, string> EnumDevices()
        {
            RegistryKey regKey, subKey;
            string portValue, path;
            int portNumber;
            Dictionary<string, string> printers = new Dictionary<string, string>();
            Dictionary<string, int> printerNames = new Dictionary<string, int>();
            try
            {
                RegistryKey nameKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Print\\Printers");
                foreach (string printer in nameKey.GetSubKeyNames())
                {
                    subKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Print\\Printers\\" + printer);
                    if (subKey.GetValue("Port") != null)
                    {
                        portValue = subKey.GetValue("Port").ToString();
                        if (portValue.Substring(0, 3) == "USB")
                        {
                            if (int.TryParse(portValue.Substring(3, portValue.Length - 3), out portNumber))
                            {
                                if (!printerNames.ContainsKey(printer))
                                    printerNames.Add(printer, portNumber);
                            }
                        }
                    }
                    subKey.Close();
                }
                nameKey.Close();
            }
            catch
            {
                //do nothing (no printers?)
            }
            try
            {
                regKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\" +
                    GUID_DEVICEINTERFACE_USBPRINT.ToString("B"));
                try
                {
                    foreach (string sub in regKey.GetSubKeyNames())
                    {
                        if (sub.Substring(0, 16).ToUpper() == "##?#USB#VID_0A5F")
                        {
                            subKey = Registry.LocalMachine.OpenSubKey(
                                string.Format("SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{0:B}\\{1}\\#",
                                GUID_DEVICEINTERFACE_USBPRINT, sub));
                            path = subKey.GetValue("SymbolicLink").ToString();
                            subKey.Close();

                            subKey = Registry.LocalMachine.OpenSubKey(
                                string.Format("SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{0:B}\\{1}\\#\\Device Parameters",
                                GUID_DEVICEINTERFACE_USBPRINT, sub));
                            if (subKey.GetValue("Port Number") != null)
                            {
                                if (int.TryParse(subKey.GetValue("Port Number").ToString(), out portNumber))
                                {
                                    if (printerNames.ContainsValue(portNumber))
                                        foreach (KeyValuePair<string, int> printerName in printerNames)
                                        {
                                            if (printerName.Value == portNumber)
                                            {
                                                printers.Add(printerName.Key, path);
                                            }
                                        }
                                }
                            }
                            subKey.Close();
                        }
                    }
                }
                finally
                {
                    regKey.Close();
                }
            }
            catch
            {
                // do nothing
            }
            return printers;
        }

file attachments

comments

Crucial wrote May 15, 2013 at 8:13 PM

Here's the entirety of the updated USBPrinter.cs file.