2009-07-04 41 views

Respuesta

11

Como otros sugirieron, puede utilizar WMI. Puede encontrar una muestra in CodeProject

try 
{ 
    ManagementObjectSearcher searcher = 
     new ManagementObjectSearcher("root\\WMI", 
     "SELECT * FROM MSSerial_PortName"); 

    foreach (ManagementObject queryObj in searcher.Get()) 
    { 
     Console.WriteLine("-----------------------------------"); 
     Console.WriteLine("MSSerial_PortName instance"); 
     Console.WriteLine("-----------------------------------"); 
     Console.WriteLine("InstanceName: {0}", queryObj["InstanceName"]); 

     Console.WriteLine("-----------------------------------"); 
     Console.WriteLine("MSSerial_PortName instance"); 
     Console.WriteLine("-----------------------------------"); 
     Console.WriteLine("PortName: {0}", queryObj["PortName"]); 

     //If the serial port's instance name contains USB 
     //it must be a USB to serial device 
     if (queryObj["InstanceName"].ToString().Contains("USB")) 
     { 
      Console.WriteLine(queryObj["PortName"] + " 
      is a USB to SERIAL adapter/converter"); 
     } 
    } 
} 
catch (ManagementException e) 
{ 
    Console.WriteLine("An error occurred while querying for WMI data: " + e.Message); 
} 
+4

Este código produce un error en la línea "foreach" en .NET Framework 4.0. –

+2

Obtengo un error de "Acceso denegado" en .NET 4.5 – Brendan

+0

¿Hay un equivalente de Python de este código en alguna parte? –

30

Framework v1.1 AFAIK no le permite hacer esto.

En 2.0 no es una función estática

SerialPort.GetPortNames() 

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames.aspx

+0

no parece funcionar para <-> dispositivos serie USB .. –

+0

Probablemente no ha instalado el controlador correctamente. ¿Aparece en el hiperterminal? – Vanuan

+0

Los controladores están instalados y se puede conectar otro software, incluido el hyperterminal. Estos son FTDI USB <-> dispositivos basados ​​en serie. Terminé usando los QueryDosDevices de esta respuesta: http://stackoverflow.com/questions/1388871/how-do-i-get-a-list-of-available-serial-ports-in-win32 –

1

WMI contiene una gran cantidad de información sobre el hardware. Consulta de instancias de Win32_SerialPort.

(otoh No puedo recordar la cantidad de apoyo consulta WMI estaba en .NET 1.1.)

1

No hay soporte para la comunicación en SerialPort v1.1 .NET. La solución más común para esto era usar el control activo MSCOMMCTL X de una instalación VB6.0 (importarlo a su proyecto .net como un componente COM desde el cuadro de diálogo Agregar referencia).

En versiones posteriores, la compatibilidad con el puerto serie está disponible a través del espacio de nombre System.IO.Ports. También tenga en cuenta que no hay API que le proporcionará la lista de puertos gratuitos.

Puede obtener una lista de todos los nombres de puertos y luego intente abrir una conexión. Se produce una excepción si el puerto ya está en uso.

0

Use QueryDosDevice Función API. Este es un fragmento de VB6:

ReDim vRet(0 To 255) 

    sBuffer = String(100000, 1) 
    Call QueryDosDevice(0, sBuffer, Len(sBuffer)) 
    sBuffer = Chr$(0) & sBuffer 
    For lIdx = 1 To 255 
     If InStr(1, sBuffer, Chr$(0) & "COM" & lIdx & Chr$(0), vbTextCompare) > 0 Then 
      vRet(lCount) = "COM" & lIdx 
      lCount = lCount + 1 
     End If 
    Next 
8

Los puertos serie disponibles también se pueden encontrar en los valores de la clave HKEY_LOCAL_MACHINE\hardware\devicemap\serialcomm en el registro.

2

¿Qué hay de hacer una pregunta directamente del sistema operativo:

using System; 
using System.Collections.Generic; 
using Microsoft.Win32; 
using System.Runtime.InteropServices; 
using Microsoft.Win32.SafeHandles; 

public class MyClass 
{ 
    private const uint GENERIC_ALL = 0x10000000; 
    private const uint GENERIC_READ = 0x80000000; 
    private const uint GENERIC_WRITE = 0x40000000; 
    private const uint GENERIC_EXECUTE = 0x20000000;  
    private const int OPEN_EXISTING = 3;  
    public const int INVALID_HANDLE_VALUE = -1; 

    public static void Main() 
    { 
     for (int i = 1; i <= 32; i++) 
      Console.WriteLine ("Port {0}: {1}", i, PortExists (i)); 
    } 

    private static bool PortExists (int number) { 
     SafeFileHandle h = CreateFile (@"\\.\COM" + number.ToString(), GENERIC_READ + GENERIC_WRITE, 
      0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); 

     bool portExists = !h.IsInvalid; 

     if (portExists) 
      h.Close(); 

     return portExists; 
    } 

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    private static extern SafeFileHandle CreateFile (string lpFileName, System.UInt32 dwDesiredAccess, 
     System.UInt32 dwShareMode, IntPtr pSecurityAttributes, System.UInt32 dwCreationDisposition, 
     System.UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile); 
} 
+3

OK ... ¡hay una trampa!Esto le dirá si hay un puerto disponible para la aplicación. Si un puerto es capturado por otra aplicación, la función PortExists devolverá falso. Si desea obtener la lista de puertos disponible en hardware (incluso si la capturan otras aplicaciones), invoque GetDefaultCommConfig (http://msdn.microsoft.com/en-us/library/aa363262(VS.85).aspx). – Hemant

+0

Gracias. Esto funcionó como el encanto. – aldoblack

1

dado que está utilizando .NET 1.1 una opción es utilizar el control AxMSCommLib.

Aquí hay una página web que me ayudó a comenzar a usar el control AxMSCommLib. Incluso hay un método FindDevicePort() en la lista que se puede modificar fácilmente.

Desde entonces he cambiado a System.IO.Ports que parece ser mucho más robusto.

http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320

Gracias

Joe

Cuestiones relacionadas