5 changed files with 117 additions and 6 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,96 @@ |
|||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
|
||||
|
|
||||
|
#include "SerialPortLibrary.h" |
||||
|
|
||||
|
#if PLATFORM_WINDOWS |
||||
|
#include "Windows/AllowWindowsPlatformTypes.h" |
||||
|
#include <windows.h> |
||||
|
#include <setupapi.h> |
||||
|
#include "Windows/HideWindowsPlatformTypes.h" |
||||
|
|
||||
|
#pragma comment(lib, "setupapi.lib") |
||||
|
#endif |
||||
|
|
||||
|
TArray<FString> USerialPortLibrary::GetAvailableSerialPorts() |
||||
|
{ |
||||
|
TArray<FString> Ports; |
||||
|
|
||||
|
#if PLATFORM_WINDOWS |
||||
|
// Query registry for all COM ports
|
||||
|
HKEY hKey; |
||||
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), |
||||
|
0, KEY_READ, &hKey) == ERROR_SUCCESS) |
||||
|
{ |
||||
|
DWORD Index = 0; |
||||
|
TCHAR ValueName[256]; |
||||
|
TCHAR ValueData[256]; |
||||
|
DWORD ValueNameSize = 256; |
||||
|
DWORD ValueDataSize = 256 * sizeof(TCHAR); |
||||
|
DWORD Type; |
||||
|
|
||||
|
while (RegEnumValue(hKey, Index++, ValueName, &ValueNameSize, |
||||
|
nullptr, &Type, (LPBYTE)ValueData, &ValueDataSize) == ERROR_SUCCESS) |
||||
|
{ |
||||
|
Ports.Add(FString(ValueData)); |
||||
|
ValueNameSize = 256; |
||||
|
ValueDataSize = 256 * sizeof(TCHAR); |
||||
|
} |
||||
|
RegCloseKey(hKey); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
return Ports; |
||||
|
} |
||||
|
|
||||
|
TArray<FString> USerialPortLibrary::GetAvailableSerialPortsWithNames() |
||||
|
{ |
||||
|
TArray<FString> Ports; |
||||
|
|
||||
|
#if PLATFORM_WINDOWS |
||||
|
// Use SetupAPI to get port + friendly device name
|
||||
|
HDEVINFO DeviceInfoSet = SetupDiGetClassDevs( |
||||
|
nullptr, TEXT("USB"), nullptr, |
||||
|
DIGCF_PRESENT | DIGCF_ALLCLASSES |
||||
|
); |
||||
|
|
||||
|
if (DeviceInfoSet == INVALID_HANDLE_VALUE) |
||||
|
return Ports; |
||||
|
|
||||
|
SP_DEVINFO_DATA DeviceInfoData; |
||||
|
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); |
||||
|
|
||||
|
for (DWORD i = 0; SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DeviceInfoData); i++) |
||||
|
{ |
||||
|
TCHAR FriendlyName[256] = {}; |
||||
|
TCHAR PortName[256] = {}; |
||||
|
|
||||
|
// Get friendly name (e.g. "Arduino Uno (COM3)")
|
||||
|
SetupDiGetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, |
||||
|
SPDRP_FRIENDLYNAME, nullptr, (PBYTE)FriendlyName, sizeof(FriendlyName), nullptr); |
||||
|
|
||||
|
// Get COM port from device registry key
|
||||
|
HKEY DevKey = SetupDiOpenDevRegKey(DeviceInfoSet, &DeviceInfoData, |
||||
|
DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); |
||||
|
|
||||
|
if (DevKey != INVALID_HANDLE_VALUE) |
||||
|
{ |
||||
|
DWORD PortNameSize = sizeof(PortName); |
||||
|
RegQueryValueEx(DevKey, TEXT("PortName"), nullptr, |
||||
|
nullptr, (LPBYTE)PortName, &PortNameSize); |
||||
|
RegCloseKey(DevKey); |
||||
|
|
||||
|
if (wcslen(PortName) > 0 && wcslen(FriendlyName) > 0) |
||||
|
{ |
||||
|
// Format: "COM3|Arduino Uno (COM3)"
|
||||
|
FString Entry = FString::Printf(TEXT("%s|%s"), PortName, FriendlyName); |
||||
|
Ports.Add(Entry); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
SetupDiDestroyDeviceInfoList(DeviceInfoSet); |
||||
|
#endif |
||||
|
|
||||
|
return Ports; |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
#pragma once |
||||
|
#include "CoreMinimal.h" |
||||
|
#include "Kismet/BlueprintFunctionLibrary.h" |
||||
|
#include "SerialPortLibrary.generated.h" |
||||
|
|
||||
|
UCLASS() |
||||
|
class SPIE_AVATAR_API USerialPortLibrary : public UBlueprintFunctionLibrary |
||||
|
{ |
||||
|
GENERATED_BODY() |
||||
|
public: |
||||
|
UFUNCTION(BlueprintPure, Category = "Serial Port") |
||||
|
static TArray<FString> GetAvailableSerialPorts(); |
||||
|
UFUNCTION(BlueprintPure, Category = "Serial Port") |
||||
|
static TArray<FString> GetAvailableSerialPortsWithNames(); |
||||
|
}; |
||||
Loading…
Reference in new issue