Frage

Ich habe ein GSM-Modem über USB angeschlossen. Das Modem schafft zwei serielle Schnittstellen. Der erste wird automatisch an das Modem angeschlossen, das zweite zeigt im Geräte-Manager als "HUAWEI Mobile Connect - 3G PC UI-Schnittstelle (COM6)"

Der zweite Anschluss wird verwendet, wichtige Informationen aus dem Modem zu bekommen, wie die Signalqualität; zum Senden und Empfangen von Textnachrichten; und eine ganze Reihe anderer Funktionen.

Ich schreibe eine Anwendung, die von dem zweiten Anschluss versehen einige der Features einpacken wird. Was ich brauche, ist eine sichere Methode des Ersatz eine ist, das COM-Port zu identifizieren. die Ports Iterieren und eine Antwort auf „ATE0“ Überprüfung ist nicht ausreichend. Die Schnittstelle des Modems ist in der Regel die niedrigeren Nummern eins, und wenn eine DFÜ-Verbindung nicht aktiv ist, wird es reagieren „ATE0“ das gleiche wie das zweite Tor.

Was ich dachte zu tun ist, um die Häfen Iterieren und ihre freundliche Namensprüfung, wie es im Geräte-Manager zeigt. im Geräte-Manager - auf diese Weise kann ich den Port in meiner Anwendung auf die "3G PC UI-Schnittstelle (COM6) HUAWEI Mobile Connect" bezeichnet Port verbinden. Ich habe nicht nur gefunden noch keine Informationen, dass mir erlaubt, programmatisch diesen Namen zu erhalten.

War es hilfreich?

Lösung

Vor langer Zeit schrieb ich ein Programm für einen Client zu tun, nur dies, sondern für ein GPS anstatt ein Modem.

Ich habe gerade es sieht, und Bits, die möglicherweise hilfreich als Sprung-out ist:

    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))
    {
...

(Sie nennen das Bit in einer Schleife mit nDevice Inkrementieren)

und dann

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

, die den Namen des Geräts findet.

Hoffentlich werden Sie in die richtige Richtung helfen.

Andere Tipps

Nachdem Sie einen seriellen Port Gerät bestimmen, ist diejenige, die Sie wollen (um seinen freundlichen Namen suchen, von der Muttergerät usw. überprüft), der richtige Weg, den Hafen der Namen bekommen würde wahrscheinlich sein:

  • aufrufen SetupDiOpenDevRegKey(hDevInfo, devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ) die HKEY auf die so genannte Geräteschlüssel zu erhalten
  • abfragen, diesen Registrierungsschlüssel für den REG_SZ Wert „Portname“
  • vergessen Sie nicht die HKEY zu schließen:)

Allerdings könnte dies so viel Interop in C # erfordern es ist auch nicht lustig, so dass ich Ihnen nicht verdenken, wenn Sie auf den String-Parsing-Lösung halten.

Die Informationen von Will Dean geschrieben war sehr hilfreich. Dies ist der Code, der schließlich für mich gearbeitet. Alles, was in der PInvoke Klasse wurde wörtlich aus http://www.pinvoke.net . Ich habe hier einen Datentyp ändern oder es ihm (wie wenn eine Enumeration anstelle eines uint) funktioniert, aber es sollte, um herauszufinden, einfach sein.

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;
}

Ich denke, die Linie Result = tmpstring.Substring(tmpstring.IndexOf("COM"),tmpstring.IndexOf(')') - tmpstring.IndexOf("COM")); ein wenig ungeschickt ist, Vorschläge, wie es zu bereinigen, würden geschätzt.

Vielen Dank für Ihre Hilfe bei dieser Angelegenheit, ohne sie, würde ich immer noch Google werden zu suchen.

Die C ++ Version basiert auf @Will Dean Antwort.

#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;
    }
}

Gut, dass es funktioniert.

Sie könnten versuchen:

Regex.Match (tmpstring, @ "COM \ s \ d +"). ToString ()

für Ihr String-Matching.

Wie .NET Style-Punkte, würde ich ein „using System.Text“, fügen Sie und ich würde nicht lokale Variablennamen mit Kapitellen beginnen, und wenn ich wirklich tugendhaft fühle, würde ich wahrscheinlich den SetupDiDestroyDeviceInfoList in einem schließlich setzen {} Klausel.

die Methode geschrieben Wird von LiGenChen . Die Methode ComPortSetupAPISetupDiClassGuids gab die beste Zeit und freundliche Namen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top