mirror of https://github.com/DJ2LS/FreeDATA.git
150 lines
4.3 KiB
Python
150 lines
4.3 KiB
Python
#! python
|
|
#
|
|
# Enumerate serial ports on Windows including a human readable description
|
|
# and hardware information using winreg.
|
|
#
|
|
# Using winreg helps find virtual comports
|
|
# Taken from https://github.com/pyserial/pyserial/pull/70 since pyserial isnt getting recent updates
|
|
try:
|
|
# Python 3.X
|
|
import winreg
|
|
except ImportError:
|
|
# Python 2.7 compatibility
|
|
try:
|
|
import _winreg as winreg
|
|
except ImportError:
|
|
winreg = None
|
|
|
|
from serial.tools import list_ports_common
|
|
from serial.tools import list_ports_windows
|
|
|
|
SERIAL_REGISTRY_PATH = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
|
|
|
|
|
|
def regval_to_listport(winport):
|
|
"""Convert a windows port from registry key to pyserial's ListPortInfo.
|
|
|
|
Args:
|
|
winport (tuple): Windows registry value (description, device, value).
|
|
|
|
Returns:
|
|
listport (ListPortInfo): comport device details.
|
|
"""
|
|
# Create the ListPortInfo
|
|
description, device, _ = winport
|
|
listport = list_ports_common.ListPortInfo(device)
|
|
|
|
# Format the description like other ListPortInfo
|
|
description = description.replace('\\Device\\', '')
|
|
listport.description = "{} ({})".format(description, device)
|
|
|
|
return listport
|
|
|
|
|
|
# end regval_to_listport
|
|
|
|
|
|
def winreg_comports():
|
|
"""Return windows comports found in the registry.
|
|
|
|
See Also:
|
|
list_ports_winreg.comports(), list_ports_winreg.comports_list(),
|
|
list_ports_windows.comports()
|
|
|
|
Note:
|
|
This should include virtual comports, and it is significantly faster
|
|
than list_ports_windows.comports(). However, list_ports_windows has far
|
|
more information. comports() contains all list_ports_windows.comports()
|
|
and winreg_comports() that were not found from list_ports_windows.
|
|
|
|
Returns:
|
|
comports (list): Sorted list of ListPortInfo.
|
|
"""
|
|
try:
|
|
# Get the Serial Coms registry
|
|
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, SERIAL_REGISTRY_PATH)
|
|
|
|
# Get key info - number of values (subkeys, num_vals, last_modified)
|
|
num_values = winreg.QueryInfoKey(key)[1]
|
|
|
|
# Make a generator of comports
|
|
for i in range(num_values):
|
|
# get registry value for the comport
|
|
value = winreg.EnumValue(key, i)
|
|
yield regval_to_listport(value)
|
|
|
|
# Close the registry key
|
|
winreg.CloseKey(key)
|
|
except (AttributeError, WindowsError, EnvironmentError):
|
|
# winreg is None or there was a key error
|
|
pass
|
|
|
|
|
|
# end winreg_comports
|
|
|
|
|
|
def comports_list():
|
|
"""Return a list of comports found from list_ports_windows and comports
|
|
found in the window registry.
|
|
|
|
See Also:
|
|
list_ports_winreg.comports(), list_ports_winreg.winreg_comports(),
|
|
list_ports_windows.comports()
|
|
|
|
Note:
|
|
This should include virtual comports. This method contains all
|
|
list_ports_windows.comports() and winreg_comports() that were not found
|
|
from list_ports_windows.
|
|
|
|
Returns:
|
|
comports (list): List of ListPortInfo comport details.
|
|
"""
|
|
comports = list(list_ports_windows.comports())
|
|
|
|
comports[len(comports):] = [li for li in winreg_comports()
|
|
if li not in comports]
|
|
|
|
return comports
|
|
|
|
|
|
# end comports_list
|
|
|
|
|
|
def comports(include_links=False):
|
|
"""Generator for comports found from list ports windows and comports found
|
|
in the windows registry.
|
|
|
|
See Also:
|
|
list_ports_winreg.comports_list(), list_ports_winreg.winreg_comports(),
|
|
list_ports_windows.comports()
|
|
|
|
Note:
|
|
This should include virtual comports. This method contains all
|
|
list_ports_windows.comports() and winreg_comports() that were not found
|
|
from list_ports_windows.
|
|
|
|
Yields:
|
|
comport (ListPortInfo): Comport details.
|
|
|
|
Returns:
|
|
comports (generator): Generator of ListPortInfo comports.
|
|
"""
|
|
existing = []
|
|
for comport in list_ports_windows.comports():
|
|
existing.append(comport)
|
|
yield comport
|
|
|
|
for li in winreg_comports():
|
|
if li not in existing:
|
|
existing.append(li)
|
|
yield li
|
|
|
|
|
|
# end comports
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
# test
|
|
if __name__ == '__main__':
|
|
for port, desc, hwid in sorted(comports()):
|
|
print("%s: %s [%s]" % (port, desc, hwid)) |