18

特定のシステムがC#を介してサポートするすべての利用可能なボーレートを確認する方法はありますか?これは[デバイスマネージャー]->[ポート]から利用できますが、プログラムで一覧表示したいと思います。

4

3 に答える 3

15

私はこれを行うためのいくつかの方法を見つけました。次の2つのドキュメントが出発点でした

手がかりは、最初のドキュメントの次の段落にあります

特定のシリアルポートで使用可能なボーレートを判別する最も簡単な方法は、GetCommProperties()アプリケーションプログラミングインターフェイス(API)を呼び出し、COMMPROP.dwSettableBaudビットマスクを調べて、そのシリアルポートでサポートされているボーレートを判別することです。

この段階では、C#でこれを行うための2つの選択肢があります。

1.0相互運用機能(P / Invoke)を次のように使用します。

次のデータ構造を定義します

[StructLayout(LayoutKind.Sequential)]
struct COMMPROP
{
    short wPacketLength;
    short wPacketVersion;
    int dwServiceMask;
    int dwReserved1;
    int dwMaxTxQueue;
    int dwMaxRxQueue;
    int dwMaxBaud;
    int dwProvSubType;
    int dwProvCapabilities;
    int dwSettableParams;
    int dwSettableBaud;
    short wSettableData;
    short wSettableStopParity;
    int dwCurrentTxQueue;
    int dwCurrentRxQueue;
    int dwProvSpec1;
    int dwProvSpec2;
    string wcProvChar;
}

次に、次の署名を定義します

[DllImport("kernel32.dll")]
static extern bool GetCommProperties(IntPtr hFile, ref COMMPROP lpCommProp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess,
           int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, 
           int dwFlagsAndAttributes, IntPtr hTemplateFile);

次に、次の呼び出しを行います(http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspxを参照) 。

   COMMPROP _commProp = new COMMPROP();
   IntPtr hFile = CreateFile(@"\\.\" + portName, 0, 0, IntPtr.Zero, 3, 0x80, IntPtr.Zero);
   GetCommProperties(hFile, ref commProp);

portNameはCOMのようなものですか?(COM1、COM2など)。これで、 commProp.dwSettableBaudに必要な情報が含まれるはずです。

2.0 C#リフレクションを使用する

リフレクションを使用してSerialPortBaseStreamにアクセスし、必要なデータを次のように使用できます。

   _port = new SerialPort(portName);
   _port.Open();
   object p = _port.BaseStream.GetType().GetField("commProp", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_port.BaseStream);
   Int32 bv = (Int32)p.GetType().GetField("dwSettableBaud", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(p);

上記の両方の方法で、このデータを取得するには、ポートを少なくとも1回開く必要があることに注意してください。


于 2009-07-23T14:26:21.497 に答える
0

私はあなたができるとは思わない。

最近この問題が発生し、使用したいボーレートをハードコーディングすることになりました。

MSDNは、「ボーレートはユーザーのシリアルドライバーでサポートされている必要があります」と単純に述べています。

于 2009-07-22T14:51:30.190 に答える
0
dwSettableBaud  gives 268894207 int (0x1006ffff)
while dwMaxBaud gives 268435456 int (0x10000000)

明らかに、これは私を助けません。だからこれは私が現在頼っているものです:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;


  public static readonly List<string> SupportedBaudRates = new List<string>
{
    "300",
    "600",
    "1200",
    "2400",
    "4800",
    "9600",
    "19200",
    "38400",
    "57600",
    "115200",
    "230400",
    "460800",
    "921600"
};

    public static int MaxBaudRate(string portName)
    {
        var maxBaudRate = 0;
        try
        {
            //SupportedBaudRates has the commonly used baudRate rates in it
            //flavor to taste
            foreach (var baudRate in ConstantsType.SupportedBaudRates)
            {
                var intBaud = Convert.ToInt32(baudRate);
                using (var port = new SerialPort(portName))
                {
                    port.BaudRate = intBaud;
                    port.Open();
                }
                maxBaudRate = intBaud;
            }
        }
        catch
        {
            //ignored - traps exception generated by
            //baudRate rate not supported
        }

        return maxBaudRate;
    }

ボーレートはコンボボックス向けであるため、文字列で表されます。

    private void CommPorts_SelectedIndexChanged(object sender, EventArgs e)
    {
        var combo = sender as ComboBox;
        if (combo != null)
        {
            var port = combo.Items[combo.SelectedIndex].ToString();
            var maxBaud = AsyncSerialPortType.MaxBaudRate(port);
            var baudRates = ConstantsType.SupportedBaudRates;
            var f = (SerialPortOpenFormType)(combo.Parent);
            f.Baud.Items.Clear();
            f.Baud.Items.AddRange(baudRates.Where(baud => Convert.ToInt32(baud) <= maxBaud).ToArray());
        }
    }

開く予定のすべてのシリアルポートでサポートされている最小ボーレートがわかっている場合は、パフォーマンスを向上させることができます。たとえば、115,200から始めることは、今世紀に製造されたシリアルポートの安全な下限のように思われます。

于 2017-02-09T23:43:40.687 に答える