Как программно найти все доступные потоки в C# (класса SerialPort )
есть ли способ узнать все доступные скорости передачи данных, которые поддержка системы через C#? Это доступно через Диспетчер устройств-->порты но я хочу перечислить их программно.
спасибо.
3 ответов
Я нашел несколько способов сделать это. Следующие два документа были отправной точкой
- http://support.microsoft.com/default.aspx/kb/99026
- http://msdn.microsoft.com/en-us/library/aa363189 (VS.85).aspx
ключ находится в следующем абзаце из первого документа
самый простой способ определить, какие скорости передачи доступны на определенном последовательном порту является вызов GetCommProperties () интерфейс прикладного программирования (API) и изучить COMMPROP.dwSettableBaud маски, чтобы определить, какие скорости поддерживаются на последовательный порт.
на этом этапе есть два варианта сделать это в C#:
1.0 используйте interop (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);
здесь имя порта что-то вроде COM?? (СОМ1, com2, и т. д.). commProp.dwSettableBaud теперь должен содержать нужную информацию.
2.0 используйте отражение C#
отражение может использоваться для доступа к SerialPort BaseStream и оттуда необходимые данные как следует:
_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);
отметим, что в обоих вышеприведенных методов порт(ы) должен быть открыт по крайней мере один раз, чтобы получить эти данные.
Я не думаю, что вы можете.
недавно у меня была эта проблема, и в итоге я жестко кодировал скорости передачи данных, которые хотел использовать.
MSDN просто заявляет: "скорость передачи данных должна поддерживаться последовательным драйвером пользователя".
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 кажется безопасным нижним пределом для последовательных портов, изготовленных в этом веке.