Comment trouver tous les programme disponible en C vitesses possibles # (classe SerialPort)

StackOverflow https://stackoverflow.com/questions/1165692

  •  19-09-2019
  •  | 
  •  

Question

Est-il possible de trouver toutes les vitesses de transmission disponibles qu'un particulier système prend en charge via C #? Il est disponible dans le Gestionnaire de périphériques -> Ports mais je veux énumérer par programme.

Était-ce utile?

La solution

J'ai trouvé deux façons de le faire. Les deux documents suivants ont été un point de départ

L'indice est dans le paragraphe suivant du premier document

  

La façon la plus simple de déterminer les vitesses de transmission sont disponibles sur un port série particulier est d'appeler l'interface de programmation d'application GetCommProperties () (API) et d'examiner les bitmask COMMPROP.dwSettableBaud pour déterminer les vitesses de transmission sont pris en charge sur le port série.

A ce stade, il y a deux choix de le faire en C #:

1.0 Utilisation PIA (P / Invoke) comme suit:

Définir la structure de données suivante

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

Définissez ensuite les signatures suivantes

[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);

faire les appels suivants (voir 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 est quelque chose comme COM ?? (COM1, COM2, etc.). commProp.dwSettableBaud doit maintenant contenir les informations souhaitées.

2.0 Utilisation réflexion C #

La réflexion peut être utilisé pour accéder à la SerialPort BaseStream et de là les données requises comme suit:

   _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);

Notez que dans les deux méthodes ci-dessus du port (s) doit être ouvert au moins une fois pour obtenir ces données.


Autres conseils

dwSettableBaud  gives 268894207 int (0x1006ffff)
while dwMaxBaud gives 268435456 int (0x10000000)

De toute évidence, cela ne me permet pas. Voilà donc ce que je compte actuellement sur:

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

Les taux de transmission sont dans les chaînes, car ils sont destinés à une zone de liste déroulante.

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

Vous pouvez améliorer les performances si vous connaissez la vitesse de transmission minimale prise en charge par tous les ports série que vous prévoyez d'ouvrir. Par exemple, en commençant par 115200 apparaît comme une limite sûre pour les ports série fabriqués dans ce siècle.

Je ne pense pas que vous pouvez.

J'ai récemment ce problème, et a fini par codage dur les vitesses de transmission que je voulais utiliser.

MSDN indique simplement: « La vitesse de transmission doit être pris en charge par le pilote de série de l'utilisateur ».

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top