16

USB経由で接続されたGSMモデムがあります。モデムは 2 つのシリアル ポートを作成します。1 つ目はモデムに自動的に接続され、2 つ目はデバイス マネージャーに「HUAWEI Mobile Connect - 3G PC UI Interface (COM6)」として表示されます。

2 番目のポートは、信号品質などの重要な情報をモデムから取得するために使用されます。テキストメッセージを送受信するため; およびその他の機能のホスト全体。

2 番目のポートによって提供される機能の一部をラップするアプリケーションを作成しています。私が必要としているのは、どの COM ポートが予備のポートであるかを確実に識別する方法です。ポートを繰り返し、「ATE0」への応答を確認するだけでは不十分です。通常、モデムのポートは番号の小さいポートで、ダイヤルアップ接続がアクティブでない場合は、2 番目のポートと同じように「ATE0」に応答します。

私が考えていたのは、デバイスマネージャーに表示されるように、ポートを繰り返して、それらのフレンドリ名を確認することです。そうすれば、アプリケーションのポートを、デバイス マネージャーの「HUAWEI Mobile Connect - 3G PC UI Interface (COM6)」というラベルの付いたポートにリンクできます。プログラムでその名前を取得できる情報をまだ見つけていません。

4

8 に答える 8

8

ずっと前に、クライアントがこれを行うためのユーティリティを作成しましたが、モデムではなく 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';
        }

デバイスの名前を見つけます。

うまくいけば、それは正しい方向にあなたを助けるでしょう.

于 2008-11-20T11:31:38.037 に答える
4

シリアル ポート デバイスが必要なものであると判断した後 (フレンドリ名を調べたり、親デバイスを確認したりして)、ポートの名前を取得する適切な方法は、おそらく次のようになります。

  • いわゆるデバイスキーSetupDiOpenDevRegKey(hDevInfo, devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)を取得するために呼び出しますHKEY
  • このレジストリ キーにREG_SZ値「PortName」を照会します
  • を閉じることを忘れないでくださいHKEY:)

ただし、これには C# での相互運用が非常に必要になる可能性があるため、おかしなことでもありません。そのため、文字列解析ソリューションを使用している場合でも、私はあなたを責めません。

于 2009-06-28T15:12:58.593 に答える
3

Will Deanによって投稿された情報が最も役に立ちました。これは、最終的に私のために働いたコードです。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"));。それをきれいにする方法についての提案をいただければ幸いです。

この件についてご協力いただきありがとうございます。ウィル、あなたがいなかったら、私はまだグーグルで検索していたでしょう。

于 2008-11-20T15:11:24.240 に答える
1

シリアルポート制御用のライブラリを構築しました。レジストリでフレンドリ名を検索できます。ここにリンクがあります。

https://github.com/kcwongjoe/serial_port

std::vector<SerialPortInfo> comPorts = SerialPort::getSerialPortList();
std::cout << comPorts[0].friendlyName << std::endl;
于 2020-11-24T06:05:51.777 に答える
1

それがうまくいったことをうれしく思います。

あなたは試すことができます:

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

あなたの文字列マッチングのために。

.NET スタイルのポイントとして、「using System.Text」を追加し、ローカル変数名を大文字で始めませんでした。また、本当に好感が持てるなら、おそらく SetupDiDestroyDeviceInfoList を finally{} 句に入れます。 .

于 2008-11-20T18:56:09.607 に答える