문제

USB를 통해 GSM 모뎀이 연결되어 있습니다. 모뎀은 2 개의 직렬 포트를 만듭니다. 첫 번째는 모뎀에 자동으로 연결되어 있으며 두 번째는 장치 관리자의 "Huawei Mobile Connect -3G PC UI 인터페이스 (COM6)"로 표시됩니다.

두 번째 포트는 신호 품질과 같은 모뎀에서 중요한 정보를 얻는 데 사용됩니다. 문자 메시지를 보내고 받기 위해; 그리고 많은 다른 기능들.

두 번째 포트에서 제공하는 기능 중 일부를 마무리하는 응용 프로그램을 작성하고 있습니다. 내가 필요한 것은 어떤 com 포트가 여분의 포트인지 식별하는 확실한 화재 방법입니다. 포트를 반복하고 "ATE0"에 대한 응답을 확인하는 것만으로는 충분하지 않습니다. 모뎀의 포트는 일반적으로 번호가 낮으며 다이얼 업 연결이 활성화되지 않으면 두 번째 포트와 동일한 "ATE0"에 응답합니다.

제가 생각하고있는 것은 장치 관리자에게 보여 주듯이 포트를 반복하고 친근한 이름을 확인하는 것입니다. 이렇게하면 장치 관리자의 "Huawei Mobile Connect -3G PC UI 인터페이스 (COM6)"라는 포트에 응용 프로그램의 포트를 연결할 수 있습니다. 나는 그 이름을 프로그래밍 방식으로 얻을 수있는 정보를 아직 찾지 못했습니다.

도움이 되었습니까?

해결책

오래 전에 나는 고객 이이 일을 할 수있는 유틸리티를 썼지 만 모뎀이 아닌 GPS를 작성했습니다.

나는 방금 그것을 보았습니다.

    GUID guid = GUID_DEVCLASS_PORTS;

SP_DEVICE_INTERFACE_DATA interfaceData;
ZeroMemory(&interfaceData, sizeof(interfaceData));
interfaceData.cbSize = sizeof(interfaceData);

SP_DEVINFO_DATA devInfoData;
ZeroMemory(&devInfoData, sizeof(devInfoData));
devInfoData.cbSize = sizeof(devInfoData);

if(SetupDiEnumDeviceInfo(
    hDeviceInfo,            // Our device tree
    nDevice,            // The member to look for
    &devInfoData
    ))
{
    DWORD regDataType;

    BYTE hardwareId[300];
    if(SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, &regDataType, hardwareId, sizeof(hardwareId), NULL))
    {
...

(NDEVICE를 증가시키는 루프 에서이 비트를 부릅니다)

그리고

BYTE friendlyName[300];
        if(SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, NULL, friendlyName, sizeof(friendlyName), NULL))
        {
            strFriendlyNames += (LPCTSTR)friendlyName;
            strFriendlyNames += '\n';
        }

장치 이름을 찾습니다.

바라건대 그것은 올바른 방향으로 당신을 도울 것입니다.

다른 팁

직렬 포트 장치를 결정한 후에는 원하는 장치가 (친숙한 이름을 보면, 부모 장치 등을 확인함으로써) 포트 이름을 얻는 적절한 방법은 다음과 같습니다.

  • 부르다 SetupDiOpenDevRegKey(hDevInfo, devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ) 얻기 위해 HKEY 소위 장치 키로
  • 이 레지스트리 키를 쿼리하십시오 REG_SZ 가치 "portname"
  • 닫는 것을 잊지 마십시오 HKEY :)

그러나 이것은 C#에 너무 많은 인터 로프가 필요할 수 있습니다. 그것은 재미 있지 않기 때문에 문자열 구문 분석 솔루션을 보관하면 당신을 비난하지 않습니다.

게시 된 정보 윌 딘 가장 도움이되었습니다. 이것은 결국 저를 위해 일한 코드입니다. Pinvoke 클래스의 모든 것은 구두로 가져 왔습니다 http://www.pinvoke.net . 데이터 유형을 여기저기서 변경해야했지만 (UINT 대신 열거를 사용할 때와 같이) 쉽게 알아낼 수 있어야합니다.

internal static string GetComPortByDescription(string Description)
{
    string Result = string.Empty;
    Guid guid = PInvoke.GUID_DEVCLASS_PORTS;
    uint nDevice = 0;
    uint nBytes = 300;
    byte[] retval = new byte[nBytes];
    uint RequiredSize = 0;
    uint PropertyRegDataType = 0;

    PInvoke.SP_DEVINFO_DATA devInfoData = new PInvoke.SP_DEVINFO_DATA();
    devInfoData.cbSize = Marshal.SizeOf(typeof(PInvoke.SP_DEVINFO_DATA));

    IntPtr hDeviceInfo = PInvoke.SetupDiGetClassDevs(
        ref guid, 
        null, 
        IntPtr.Zero, 
        PInvoke.DIGCF.DIGCF_PRESENT);

    while (PInvoke.SetupDiEnumDeviceInfo(hDeviceInfo, nDevice++, ref devInfoData))
    {
        if (PInvoke.SetupDiGetDeviceRegistryProperty(
                hDeviceInfo, 
                ref devInfoData, 
                PInvoke.SPDRP.SPDRP_FRIENDLYNAME,
                out PropertyRegDataType, 
                retval, 
                nBytes, 
                out RequiredSize))
        {
            if (System.Text.Encoding.Unicode.GetString(retval).Substring(0, Description.Length).ToLower() ==
                Description.ToLower())
            {
                string tmpstring = System.Text.Encoding.Unicode.GetString(retval);
                Result = tmpstring.Substring(tmpstring.IndexOf("COM"),tmpstring.IndexOf(')') - tmpstring.IndexOf("COM"));
            } // if retval == description
        } // if (PInvoke.SetupDiGetDeviceRegistryProperty( ... SPDRP_FRIENDLYNAME ...
    } // while (PInvoke.SetupDiEnumDeviceInfo(hDeviceInfo, nDevice++, ref devInfoData))

    PInvoke.SetupDiDestroyDeviceInfoList(hDeviceInfo);
    return Result;
}

나는 라인을 생각한다 Result = tmpstring.Substring(tmpstring.IndexOf("COM"),tmpstring.IndexOf(')') - tmpstring.IndexOf("COM")); 약간 서투른 것입니다. 청소 방법에 대한 제안은 감사 할 것입니다.

이 문제에 대한 도움을 주셔서 감사합니다. 당신 없이도 여전히 Google을 검색 할 것입니다.

@Will Dean 답변을 기반으로 한 C ++ 버전.

#include <windows.h>
#include <initguid.h>
#include <devguid.h>
#include <setupapi.h>

void enumerateSerialPortsFriendlyNames()
{
    SP_DEVINFO_DATA devInfoData = {};
    devInfoData.cbSize = sizeof(devInfoData);

    // get the tree containing the info for the ports
    HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS,
                                               0,
                                               nullptr,
                                               DIGCF_PRESENT
                                               );
    if (hDeviceInfo == INVALID_HANDLE_VALUE)
    {
        return;
    }

    // iterate over all the devices in the tree
    int nDevice = 0;
    while (SetupDiEnumDeviceInfo(hDeviceInfo,            // Our device tree
                                 nDevice++,            // The member to look for
                                 &devInfoData))
    {
        DWORD regDataType;
        DWORD reqSize = 0;

        // find the size required to hold the device info
        SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, nullptr, nullptr, 0, &reqSize);
        BYTE* hardwareId = new BYTE[(reqSize > 1) ? reqSize : 1];
        // now store it in a buffer
        if (SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, &regDataType, hardwareId, sizeof(hardwareId) * reqSize, nullptr))
        {
            // find the size required to hold the friendly name
            reqSize = 0;
            SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
            BYTE* friendlyName = new BYTE[(reqSize > 1) ? reqSize : 1];
            // now store it in a buffer
            if (!SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, friendlyName, sizeof(friendlyName) * reqSize, nullptr))
            {
                // device does not have this property set
                memset(friendlyName, 0, reqSize > 1 ? reqSize : 1);
            }
            // use friendlyName here
            delete[] friendlyName;
        }
        delete[] hardwareId;
    }
}

일해서 다행입니다.

당신은 시도 할 수 있습니다 :

regex.match (tmpstring, @"com s d+"). tostring ()

당신의 끈 일치.

.NET 스타일 포인트로서 "System.Text 사용"을 추가하고 Capitals와 함께 로컬 변수 이름을 시작하지 않을 것이며, 정말 덕이라면 SetupDidStrepoyDeviceInfolist를 최종적으로 {} Clause에 넣을 것입니다. .

게시 된 방법을 사용했습니다 Ligenchen. ComportSetUpIpisetUpdiclassGuid 방법은 최고의 시간과 친근한 이름을 부여했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top