none
Mit C# nach bestimmtem USB-Device suchen RRS feed

  • Frage

  • Hallo,

    ich möchte mit C# in meiner Anwendung feststellen ob ein bestimmtes USB-Device sich am PC angemeldet hat. bzw. ob es richtig angeschlossen ist.

    Ich möchte also lediglich anhand des bekannten Namen des Gerätes prüfen, ob es auch vorhanden ist. Ich bekomms nicht hin, wie geht sowas?

    Zum Programmieren habe ich Visual Studio C# 2005 & 2010 Express installiert.

    Bin gespannt auf Eure Hilfen & Antworten.

    Grüße, Jochen

    Freitag, 12. August 2011 09:16

Antworten

  • Also DriveInfo wäre also am einfachsten [Edit: oder eben sehr effizient und einfach und typsicher IMHO am besten die Lösung von mir unten (also nicht die in diesem Posting)]
    Will man noch "Plug & Play Geräte" hinzubekommen kann man meinen Link mit der VBScript-Lösung im ersten Posting von mir benutzen.
    Auch, wenn WMI potentiell eher langsam ist, habe ich mal ein Beispiel (+ Projekt) gemacht, das typsichere Klassen (über mgmtclassgen erstellt) benutzt, die sogar automatisch (ggf.) deutsch dokumentiert sind. Das sieht dann auch im Coding sehr einfach aus:

        // inspiriert aus meinem Link: http://blogs.msdn.com/b/powershell/archive/2007/02/24/displaying-usb-devices-using-wmi.aspx  
        static void Main(string[] args)
        {
          var usbController = USBControllerDevice.GetInstances().Cast<USBControllerDevice>();
          var pnpGeräte = PnPEntity.GetInstances().Cast<PnPEntity>().
            Where(p => usbController.Any(uc => uc.Dependent.RelativePath.
              Split('\"')[1].Replace(@"\\", @"\") == p.DeviceID) && p.Status == "OK");
          Anzeige(pnpGeräte); Console.ReadLine();
        }

        private static void Anzeige(IEnumerable<PnPEntity> pnpGeräte)
        {
          foreach (var gerät in pnpGeräte)
            Console.WriteLine("\r\nCaption: " + gerät.Caption + "\r\n" +
              "    DeviceID: " + gerät.DeviceID + "\r\n" +
              "    Beschreibung: " + gerät.Description);
        }

    [Download Beispielprojekt]


    ciao Frank
    Sonntag, 14. August 2011 07:37
  • Hallo Jochen,

    Du könntest über Windows Management Instrumentation (WMI) nach einem beliebigen USB-Gerät suchen (von Scanner, Maus, Stick, Festplatte, Kamera und bis hin zum USB-Bleistiftspitzer ;-)

    In etwa so:

    using System;
    using System.Management; // in: System.Management.dll
    
    namespace ConsoleApplication1 { 
     public class Program { 
    
     public static void Main() {
     // Ist meine Digitalkamera angeschlossen?
     bool isDeviceFound = FindFirstDeviceByCaption("OLYMPUS C770UZ USB Device");
    
     Console.WriteLine("\nGerät gefunden: {0}", isDeviceFound ? "JA" : "NEIN");
     Console.ReadKey(true);
     }
    
     public static bool FindFirstDeviceByCaption(string deviceCaption){
     string scope = "root\\CIMV2";
     string query = String.Format("SELECT * FROM Win32_PnPEntity WHERE Caption='{0}'", deviceCaption);
     using (ManagementObjectSearcher objectSearcher = 
     new ManagementObjectSearcher(scope, query)){
     foreach (ManagementObject managementObject in objectSearcher.Get()){
     foreach (PropertyData property in managementObject.Properties){
     // Eigenschaften des gefundenen Gerätes anzeigen
     Console.WriteLine("Eigenschaft: {0}={1}", property.Name, property.Value);
     }
     return true;
     }
     return false;
     }
     }
     } 
    }
    


    Und solltest Du eine noch detailliertere Auflistung zu USB- bzw. PnP-Geräten benötigen,
    könntest Du auch mehrere WMI-Queries miteinander kombinieren:

    using (ManagementObjectSearcher usbSearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_USBControllerDevice"))
    {
     foreach (ManagementObject usbObject in usbSearcher.Get())
     {
     string deviceName = ((string)usbObject["Dependent"]).Replace("\"", String.Empty);
     string[] names = deviceName.Split('=');
     deviceName = names[1];
     using (ManagementObjectSearcher pnpSearcher = new ManagementObjectSearcher("root\\CIMV2", String.Format("SELECT * FROM Win32_PnPEntity WHERE DeviceID = '{0}'", deviceName)))
     {
     foreach (ManagementObject pnpObject in pnpSearcher.Get())
     {
     Console.WriteLine("\nDescription: {0}", pnpObject["Description"]);
     foreach (PropertyData property in pnpObject.Properties)
      Console.WriteLine("Eigenschaft: {0}={1}", property.Name, property.Value);
     }
     }
     }
    }
    
    


    Viel Glück! 

    Win32_PnPEntity Class:
    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/8d81b8a3-c101-4b47-8274-dd743fa41ec4/

    Win32_USBControllerDevice Class:
    http://msdn.microsoft.com/en-us/library/aa394505(v=vs.85).aspx

    Gruß
    Marcel

    Samstag, 13. August 2011 13:31
    Moderator
  • Hallo Jochen,

    Frank schrieb:

    Ich habe das jetzt auch mal als Projekt erstellt [Download hier] (VS 2010 Projekt).
    Die Methode "FindFirstDeviceByCaption" wird dadurch extremst vereinfacht und ich benutzte die oben angegebene Lib (in der ich einfach die schon vorhandene Methode "FindDeviceByInstanceID" benutze. Die Zeit ist dann von 10 Sekunden auf 30 Millisekunden geschrumpft:

    [@Edit: eigene Methode für USB.FindDeviceByCaption ersetzt]

     public static bool FindFirstDeviceByCaption(string deviceCaption)
     {
     USB.USBDevice usbDevice = USB.FindDeviceByCaption(deviceCaption);
     return (usbDevice != null); // gemessene Zeit: 30 Millisekunden, mit WMI: 10 Sekunden
     }
    

    Ich denke, das ist die effiktivste, und einfachste Art die USB-Device-Verfügbarkeit zu suchen (oder aufzulisten) - und noch dazu als typsichere USBDevice-Klasse.


    ciao Frank

    Montag, 15. August 2011 17:01
  • Da es bei mir jetzt funktioniert wollte ich mal eb
    en den Code hier auflisten.

    Ich habe das ganze noch soweit erweitert, daß aus einem variablen txt-File nun die Liste erweitert werden kann und dort noch unterschieden wird ob die Überprüfung des USB an oder aus ist (ist wichtig, da das Prog ja noch mehr Abläufe hat und dies nur ein Teil ist)

    Beispielinhalt der TXT-Datei:

    Gerät 1 - mit USB
    Gerät 2 - mit USB
    Gerät 3 - ohne USB 

     

    Code von Program.cs:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;
    using System.Management;
    using System.IO; 
    using System.Collections;
    
    
    namespace USB
    {
     public partial class Form1 : Form
     {
     public Form1()
     {
     InitializeComponent();
    
    
     try
     {
     cmbUSB_Devices.Items.Clear();
     StreamReader datei2;
     datei2 = File.OpenText("USB_Namen.txt");
     while (datei2.Peek() != -1)
     {
     string k = datei2.ReadLine();
     if (k == "")
     {
     k = "keine Liste vorhanden";
     }
     cmbUSB_Devices.Items.Add(k);
     }
     datei2.Close();
     }
     catch (SystemException)
     {
     MessageBox.Show("Es ist keine USB Device Liste (USB_Namen.txt) vorhanden.");
     } 
    
     
    
     
    
     private void btnStartProg_Click(object sender, EventArgs e)
     {
    
    
     //Nach USB-Device suchen
     string device = "";
     if (cmbUSB_Devices.SelectedItem != null)
     {
     device = cmbUSB_Devices.SelectedItem.ToString();
     if (device.Contains("mit USB")) //prüfen, ob USB relevant ist
     {
     string[] _device = device.Split('-'); //String auftelen auf den Textbereich vor und nach dem "-"
     int length = _device[0].Length; //Stringlänge feststellen vom ersten String, da nur dieser relevant ist
     bool isDeviceFound = USB_.FindFirstDeviceByCaption(_device[0].Remove(length-1)); //Entfernen des letzten Zeichens, da es ein Leerzeichen ist
     if (isDeviceFound == true)
     {
     //Ausgabetext und Farbe setzen
     lblUSB_Device.Text = device + " gefunden";
     lblUSB_Device.BackColor = System.Drawing.Color.Green;
     }
     else
     {
     //Ausgabetext und Farbe setzen
     lblUSB_Device.Text = device + " nicht als USB gefunden";
     lblUSB_Device.BackColor = System.Drawing.Color.Red;
     }
     }
     else //wenn USB nicht relevant ist
     {
     //Ausgabetext und Farbe setzen
     lblUSB_Device.Text = "Überprufung USB ausgeschaltet";
     lblUSB_Device.BackColor = System.Drawing.Color.Yellow;
     }
     }
     else
     //falsche oder keine Auswahl in ComboBox
     MessageBox.Show("Bitte das USB Device aus der Liste wählen!", "Fehler");
     }
     
     
     }
    
     }
    
     }
    
    
    

     


    und noch die USB_.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.IO.Ports;
    using System.Management;
    
    namespace USB
    
     class USB_
     {
     /// <summary>
     /// Nach USB-Device in USB-Geräten suchen
     /// </summary>
     /// <param name="deviceCaption"></param>
     /// <returns></returns>
     public static bool FindFirstDeviceByCaption(string deviceCaption)
     {
     string scope = "root\\CIMV2";
     string query = String.Format("SELECT * FROM Win32_PnPEntity WHERE Caption='{0}'", deviceCaption);
     using (ManagementObjectSearcher objectSearcher =
     new ManagementObjectSearcher(scope, query))
     {
     foreach (ManagementObject managementObject in objectSearcher.Get())
     {
     foreach (PropertyData property in managementObject.Properties)
     {
     // Eigenschaften des gefundenen Gerätes anzeigen
     Console.WriteLine("Eigenschaft: {0}={1}", property.Name, property.Value);
     }
     return true;
     }
     return false;
     }
     }
     }
    }
    
    

    So...jetzt hoffe ich mal, daß dies dem Nächsten der dasselbe Problem hat wie ich hatte bei der Lösung hilft ;-)

     

    Nochmals ein grooooooooooßes DANKE! für Eure geniale(n) Hilfe(n) :-)

     


    Grüße, Jochen



    • Als Antwort markiert morfeus3009 Mittwoch, 17. August 2011 08:58
    Mittwoch, 17. August 2011 08:28
  • Hallo Jochen,

    ich habe Deinen Quellcode ja hier (AnsteuerungHP) für Dich veröffentlicht gehabt.
    Nun, da wäre viel zu tun, aber was das Problem hier angeht, füge einmal folgende Methode in die USBLib ein:

     

    static public USBDevice FindDeviceByCaption(string caption)
    {
     USBDevice foundDevice = null;
    
     foreach (USBController Controller in GetHostControllers())
     {
      SearchHubCaption(Controller.GetRootHub(), ref foundDevice, caption);
      if (foundDevice != null)
       break;
     }
     return foundDevice;
    }
    
    private static void SearchHubCaption(USBHub uSBHub, ref USBDevice foundDevice, string caption)
    {
     foreach (USBPort Port in uSBHub.GetPorts())
     {
      if (Port.IsHub)
      {
       // recursive
       SearchHubCaption(Port.GetHub(), ref foundDevice, caption);
      }
      else
      {
       if (Port.IsDeviceConnected)
       {
        USBDevice Device = Port.GetDevice();
        if (Device.DeviceName == caption)
        {
         foundDevice = Device;
         break;
        }
       }
      }
     }
    }
    

     

    _______________________

     

    Rufe die Methode dann so auf:

     

     USB.USBDevice usbDevice = USB.FindDeviceByCaption(device.Trim());
     bool isDeviceFound = (usbDevice != null);
    


    Dann hast Du noch beim Einlesen aus den "USBNamen.txt" vergessen, auch Umlaute zu ermöglichen. Nimm ggf.:

     string[] usbCations = File.ReadAllLines("USB_Namen.txt", Encoding.Default);
     if (usbCations.Length == 0) cmbUSB_Devices.Items.Add("keine Liste vorhanden");
     else cmbUSB_Devices.Items.AddRange(usbCations);
    

     

    Dann - wenn Du Leerzeichen am Ende o.ä. wegnehmen willst nimm Trim().
    Dein Splitting des "USB" ist sehr "gefährlich" und liefert z.T. falsche Ergebnisse.
    Debugge das ganz genau, es muss die wirkliche Caption jedenfalls in der Methode FindDeviceByCaption "ankommen" und gesucht werden.

    ___________________________

    BTW: eine weitere gute effizente USB-Library ist:
    http://sourceforge.net/projects/usbviewerincsha/
    mit guter TreeView-Darstellung.
    Sie nutzt übrigens auch die von mir empfohlenen SetupDi**** - Methoden in der anderen USBLib.


    ciao Frank

    • Als Antwort markiert morfeus3009 Donnerstag, 18. August 2011 10:03
    • Tag als Antwort aufgehoben morfeus3009 Donnerstag, 18. August 2011 10:51
    • Als Antwort markiert morfeus3009 Donnerstag, 18. August 2011 10:52
    Donnerstag, 18. August 2011 09:28

Alle Antworten

  • Hallo Jochen,

    zum Beispiel:

    [windows - How do I detect when a removable disk is inserted using C#? - Stack Overflow]
    http://stackoverflow.com/questions/271238/how-do-i-detect-when-a-removable-disk-is-inserted-using-c

    [Detecting USB Drive Removal in a C# Program - CodeProject]
    http://www.codeproject.com/KB/system/DriveDetector.aspx

    hier sind auch ein paar Threads aus dieser Gruppe, in der einige Infos bzgl.USB mit C# stehen:

    [USB Info's]
    http://social.msdn.microsoft.com/Forums/de/visualcsharpde/thread/86fc532b-858f-4840-824c-f249304f9c62

    [Anzeigename aus dem Gerätemanager]
    http://social.msdn.microsoft.com/Forums/de-DE/visualcsharpde/thread/06553161-8fb3-443a-b53a-ef8ddec66302

     


    ciao Frank
    Freitag, 12. August 2011 13:17
  • Hallo Jochen,

    Du könntest über Windows Management Instrumentation (WMI) nach einem beliebigen USB-Gerät suchen (von Scanner, Maus, Stick, Festplatte, Kamera und bis hin zum USB-Bleistiftspitzer ;-)

    In etwa so:

    using System;
    using System.Management; // in: System.Management.dll
    
    namespace ConsoleApplication1 { 
     public class Program { 
    
     public static void Main() {
     // Ist meine Digitalkamera angeschlossen?
     bool isDeviceFound = FindFirstDeviceByCaption("OLYMPUS C770UZ USB Device");
    
     Console.WriteLine("\nGerät gefunden: {0}", isDeviceFound ? "JA" : "NEIN");
     Console.ReadKey(true);
     }
    
     public static bool FindFirstDeviceByCaption(string deviceCaption){
     string scope = "root\\CIMV2";
     string query = String.Format("SELECT * FROM Win32_PnPEntity WHERE Caption='{0}'", deviceCaption);
     using (ManagementObjectSearcher objectSearcher = 
     new ManagementObjectSearcher(scope, query)){
     foreach (ManagementObject managementObject in objectSearcher.Get()){
     foreach (PropertyData property in managementObject.Properties){
     // Eigenschaften des gefundenen Gerätes anzeigen
     Console.WriteLine("Eigenschaft: {0}={1}", property.Name, property.Value);
     }
     return true;
     }
     return false;
     }
     }
     } 
    }
    


    Und solltest Du eine noch detailliertere Auflistung zu USB- bzw. PnP-Geräten benötigen,
    könntest Du auch mehrere WMI-Queries miteinander kombinieren:

    using (ManagementObjectSearcher usbSearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_USBControllerDevice"))
    {
     foreach (ManagementObject usbObject in usbSearcher.Get())
     {
     string deviceName = ((string)usbObject["Dependent"]).Replace("\"", String.Empty);
     string[] names = deviceName.Split('=');
     deviceName = names[1];
     using (ManagementObjectSearcher pnpSearcher = new ManagementObjectSearcher("root\\CIMV2", String.Format("SELECT * FROM Win32_PnPEntity WHERE DeviceID = '{0}'", deviceName)))
     {
     foreach (ManagementObject pnpObject in pnpSearcher.Get())
     {
     Console.WriteLine("\nDescription: {0}", pnpObject["Description"]);
     foreach (PropertyData property in pnpObject.Properties)
      Console.WriteLine("Eigenschaft: {0}={1}", property.Name, property.Value);
     }
     }
     }
    }
    
    


    Viel Glück! 

    Win32_PnPEntity Class:
    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/8d81b8a3-c101-4b47-8274-dd743fa41ec4/

    Win32_USBControllerDevice Class:
    http://msdn.microsoft.com/en-us/library/aa394505(v=vs.85).aspx

    Gruß
    Marcel

    Samstag, 13. August 2011 13:31
    Moderator
  • Nochmal dazu:

    wenn es nur darum geht den existierenden Namen des USB-Gerätes zu prüfen, ist ggf. folgendes auch ohne WMI o.ä. möglich:

      private void Form1_Load(object sender, EventArgs e)
      {
       string zuSuchenderGerätename = "Dzaebel";
       DriveInfo gerät = Gerät(zuSuchenderGerätename);
       if (gerät != null)
        MessageBox.Show("Gerät <" + zuSuchenderGerätename + "> " +
         "ist aktiv (" + gerät.DriveType + ")");
       else MessageBox.Show("Gerät <" + zuSuchenderGerätename + "> " +
        "ist nicht aktiv!");
      }
    
      private DriveInfo Gerät(string name)
      {
       foreach (DriveInfo drive in DriveInfo.GetDrives())
       {
        try
        {
         if (drive.VolumeLabel == name && drive.IsReady) return drive;
        }
        catch { }
       }
       return null;
      }
    


    ciao Frank
    Samstag, 13. August 2011 15:23
  • Also DriveInfo wäre also am einfachsten [Edit: oder eben sehr effizient und einfach und typsicher IMHO am besten die Lösung von mir unten (also nicht die in diesem Posting)]
    Will man noch "Plug & Play Geräte" hinzubekommen kann man meinen Link mit der VBScript-Lösung im ersten Posting von mir benutzen.
    Auch, wenn WMI potentiell eher langsam ist, habe ich mal ein Beispiel (+ Projekt) gemacht, das typsichere Klassen (über mgmtclassgen erstellt) benutzt, die sogar automatisch (ggf.) deutsch dokumentiert sind. Das sieht dann auch im Coding sehr einfach aus:

        // inspiriert aus meinem Link: http://blogs.msdn.com/b/powershell/archive/2007/02/24/displaying-usb-devices-using-wmi.aspx  
        static void Main(string[] args)
        {
          var usbController = USBControllerDevice.GetInstances().Cast<USBControllerDevice>();
          var pnpGeräte = PnPEntity.GetInstances().Cast<PnPEntity>().
            Where(p => usbController.Any(uc => uc.Dependent.RelativePath.
              Split('\"')[1].Replace(@"\\", @"\") == p.DeviceID) && p.Status == "OK");
          Anzeige(pnpGeräte); Console.ReadLine();
        }

        private static void Anzeige(IEnumerable<PnPEntity> pnpGeräte)
        {
          foreach (var gerät in pnpGeräte)
            Console.WriteLine("\r\nCaption: " + gerät.Caption + "\r\n" +
              "    DeviceID: " + gerät.DeviceID + "\r\n" +
              "    Beschreibung: " + gerät.Description);
        }

    [Download Beispielprojekt]


    ciao Frank
    Sonntag, 14. August 2011 07:37
  • Vielen Dank Euch für die Antworten!

    Ich werde es nachher gleich mal testen und schauen, welcher Lösungsvorschlag der passendste für mich ist.

     

    Achso...eine Frage hab ich zu Euren Vorschlägen noch:

    Sind die nur für C# 2010er Express oder auch für 2005er?

    (hab gelesen, daß man wohl mit der 2005er keinerlei Zugriff auf USB haben kann?!)


    Grüße, Jochen
    Montag, 15. August 2011 05:22
  • Hallo Jochen,

    meine Quellcodes sollten auch über VS 2005 (unabhängig von Express oder nicht) funktionieren, obwohl heutzutage natürlich eher VS 2010 benutzt wird.

    Ein detailliertes Beispiel-Projekt auch mit Win32-API-Aufrufen wie SetupDiEnumDeviceInfo (die potentiell recht schnell sind) kannst Du übrigens hier einsehen (VS 2005 Projekt): http://emmet-gray.com/Programs/Developer%20Tools/USBView.zip [dort ist es in Projekt: USBLib/Functions.cs/Klasse: USB/ die Methode: GetConnectedDevices()].


    ciao Frank
    Montag, 15. August 2011 05:56
  • Super!!!

    Ich danke euch...es klappt :-)

    Hab den Vorschlag von Marcel genommen (das erste Beispiel), aber ist auf jeden Fall spitzenmäßig mehrere Wege zu sehen und den mit den DrivInfo werd ich bestimmt auch mal noch brauchen können, nur das was ich jetzt wissen wil ist n stupides Gerät an USB...

    Als nochmals besten Dank! ;-)


    Grüße, Jochen
    Montag, 15. August 2011 06:38
  • Hallo Jochen,

    Frank schrieb:

    Ich habe das jetzt auch mal als Projekt erstellt [Download hier] (VS 2010 Projekt).
    Die Methode "FindFirstDeviceByCaption" wird dadurch extremst vereinfacht und ich benutzte die oben angegebene Lib (in der ich einfach die schon vorhandene Methode "FindDeviceByInstanceID" benutze. Die Zeit ist dann von 10 Sekunden auf 30 Millisekunden geschrumpft:

    [@Edit: eigene Methode für USB.FindDeviceByCaption ersetzt]

     public static bool FindFirstDeviceByCaption(string deviceCaption)
     {
     USB.USBDevice usbDevice = USB.FindDeviceByCaption(deviceCaption);
     return (usbDevice != null); // gemessene Zeit: 30 Millisekunden, mit WMI: 10 Sekunden
     }
    

    Ich denke, das ist die effiktivste, und einfachste Art die USB-Device-Verfügbarkeit zu suchen (oder aufzulisten) - und noch dazu als typsichere USBDevice-Klasse.


    ciao Frank

    Montag, 15. August 2011 17:01
  • Hallo Jochen,

    meine Quellcodes sollten auch über VS 2005 (unabhängig von Express oder nicht) funktionieren, obwohl heutzutage natürlich eher VS 2010 benutzt wird.

    Ein detailliertes Beispiel-Projekt auch mit Win32-API-Aufrufen wie SetupDiEnumDeviceInfo (die potentiell recht schnell sind) kannst Du übrigens hier einsehen (VS 2005 Projekt): http://emmet-gray.com/Programs/Developer%20Tools/USBView.zip [dort ist es in Projekt: USBLib/Functions.cs/Klasse: USB/ die Methode: GetConnectedDevices()].


    ciao Frank

    Hallo Frank,

    mal ne echt vermutlich dumme Frage:

    Wenn ich die Functions.cs dem Projekt hinzufüge bekomme ich Fehlermeldungen, daß Verweise fehlen.

    Ich vermute mal die "System.Runtime.InteropServices" und "System.Diagnostics"

    Kann es sein, daß die im .NET Framework 4 sind und dieses mit C#2005Express nicht funzt?


    Grüße, Jochen
    Dienstag, 16. August 2011 05:22
  • Hallo Jochen,

    beides ist in .NET 2.0 auch vorhanden. Siehe:

      http://msdn.microsoft.com/de-de/library/system.runtime.interopservices(v=VS.80).aspx

      http://msdn.microsoft.com/de-de/library/system.diagnostics(v=VS.80).aspx

    Es wird sicherlich die ein oder andere Klasse nicht geben. Aber ohne die genaue und vollständige Fehlermeldung kann man darüber nur mutmaßen.

    Allerdings schriebst Du in deinem Eingangsposting, dass Du auch C# 2010 hast. Von daher wäre es auch sinnvoll, das (mit .NET 4) zu verwenden.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Dienstag, 16. August 2011 05:58
    Moderator
  • Hallo Jochen,

    Zunächst, es geht alles auch mit VS 2005. Direkt solltest Du die Functions.cs nicht zufügen (->Separation of Concerns) - es würde ja sonst auch USB.cs fehlen.
    Du solltest - wie in meinem Beispiel - das Projekt USBLib (wie in meinem Download) möglichst in einen eigenen Ordner neben Deinem Hauptprojekt kopieren und dann über Visual Studio (auch Express 2005) über "RechteMaus auf die Solution / Hinzufügen / Vorhandenenes Projekt" dieses USBLib-Projekt hinzufügen. Vielleicht hast Du das auch schon gemacht.
    Dann fügst Du in Deinem Hauptprojekt über Verweis / Hinzufügen den Projektlink auf die USBLib hinzu.
    Wichtig ist dann ggf. noch, dass Du ein:

     using USBLib;

    oben einfügst, damit "USB.FindDeviceByInstanceID(deviceCaption);" aufgelöst wird. 

     

    ____________________________

    BTW: eine weitere gute effizente USB-Library ist:
    http://sourceforge.net/projects/usbviewerincsha/
    mit guter TreeView-Darstellung.
    Sie nutzt übrigens auch die von mir empfohlenen SetupDi**** - Methoden in der anderen USBLib.


    ciao Frank



    Dienstag, 16. August 2011 06:19
  • Hallo Jochen,

    beides ist in .NET 2.0 auch vorhanden. Siehe:

      http://msdn.microsoft.com/de-de/library/system.runtime.interopservices(v=VS.80).aspx

      http://msdn.microsoft.com/de-de/library/system.diagnostics(v=VS.80).aspx

    Es wird sicherlich die ein oder andere Klasse nicht geben. Aber ohne die genaue und vollständige Fehlermeldung kann man darüber nur mutmaßen.

    Allerdings schriebst Du in deinem Eingangsposting, dass Du auch C# 2010 hast. Von daher wäre es auch sinnvoll, das (mit .NET 4) zu verwenden.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Das mit C# 2010 müssen wir erst in der Firma klären, da wir aktuell halt immer noch C# 2005 verwenden.

    Da aber die Kollegen grad im Urlaub sind, kann ich nciht einfach mal so unseren Standard wechseln ;-)

    Aber ich werde das auf alle Fälle ansprechen und es spricht ja auch eigentlich nichts dagegen: alte 2005er Projekte können importiert werden (vermute und hoffe ich mal) es sind neue bessere Funktionalitäten hinzugekommen im Vergleich 2005<>2010

     


    Grüße, Jochen
    Dienstag, 16. August 2011 09:54
  • Da es bei mir jetzt funktioniert wollte ich mal eb
    en den Code hier auflisten.

    Ich habe das ganze noch soweit erweitert, daß aus einem variablen txt-File nun die Liste erweitert werden kann und dort noch unterschieden wird ob die Überprüfung des USB an oder aus ist (ist wichtig, da das Prog ja noch mehr Abläufe hat und dies nur ein Teil ist)

    Beispielinhalt der TXT-Datei:

    Gerät 1 - mit USB
    Gerät 2 - mit USB
    Gerät 3 - ohne USB 

     

    Code von Program.cs:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;
    using System.Management;
    using System.IO; 
    using System.Collections;
    
    
    namespace USB
    {
     public partial class Form1 : Form
     {
     public Form1()
     {
     InitializeComponent();
    
    
     try
     {
     cmbUSB_Devices.Items.Clear();
     StreamReader datei2;
     datei2 = File.OpenText("USB_Namen.txt");
     while (datei2.Peek() != -1)
     {
     string k = datei2.ReadLine();
     if (k == "")
     {
     k = "keine Liste vorhanden";
     }
     cmbUSB_Devices.Items.Add(k);
     }
     datei2.Close();
     }
     catch (SystemException)
     {
     MessageBox.Show("Es ist keine USB Device Liste (USB_Namen.txt) vorhanden.");
     } 
    
     
    
     
    
     private void btnStartProg_Click(object sender, EventArgs e)
     {
    
    
     //Nach USB-Device suchen
     string device = "";
     if (cmbUSB_Devices.SelectedItem != null)
     {
     device = cmbUSB_Devices.SelectedItem.ToString();
     if (device.Contains("mit USB")) //prüfen, ob USB relevant ist
     {
     string[] _device = device.Split('-'); //String auftelen auf den Textbereich vor und nach dem "-"
     int length = _device[0].Length; //Stringlänge feststellen vom ersten String, da nur dieser relevant ist
     bool isDeviceFound = USB_.FindFirstDeviceByCaption(_device[0].Remove(length-1)); //Entfernen des letzten Zeichens, da es ein Leerzeichen ist
     if (isDeviceFound == true)
     {
     //Ausgabetext und Farbe setzen
     lblUSB_Device.Text = device + " gefunden";
     lblUSB_Device.BackColor = System.Drawing.Color.Green;
     }
     else
     {
     //Ausgabetext und Farbe setzen
     lblUSB_Device.Text = device + " nicht als USB gefunden";
     lblUSB_Device.BackColor = System.Drawing.Color.Red;
     }
     }
     else //wenn USB nicht relevant ist
     {
     //Ausgabetext und Farbe setzen
     lblUSB_Device.Text = "Überprufung USB ausgeschaltet";
     lblUSB_Device.BackColor = System.Drawing.Color.Yellow;
     }
     }
     else
     //falsche oder keine Auswahl in ComboBox
     MessageBox.Show("Bitte das USB Device aus der Liste wählen!", "Fehler");
     }
     
     
     }
    
     }
    
     }
    
    
    

     


    und noch die USB_.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.IO.Ports;
    using System.Management;
    
    namespace USB
    
     class USB_
     {
     /// <summary>
     /// Nach USB-Device in USB-Geräten suchen
     /// </summary>
     /// <param name="deviceCaption"></param>
     /// <returns></returns>
     public static bool FindFirstDeviceByCaption(string deviceCaption)
     {
     string scope = "root\\CIMV2";
     string query = String.Format("SELECT * FROM Win32_PnPEntity WHERE Caption='{0}'", deviceCaption);
     using (ManagementObjectSearcher objectSearcher =
     new ManagementObjectSearcher(scope, query))
     {
     foreach (ManagementObject managementObject in objectSearcher.Get())
     {
     foreach (PropertyData property in managementObject.Properties)
     {
     // Eigenschaften des gefundenen Gerätes anzeigen
     Console.WriteLine("Eigenschaft: {0}={1}", property.Name, property.Value);
     }
     return true;
     }
     return false;
     }
     }
     }
    }
    
    

    So...jetzt hoffe ich mal, daß dies dem Nächsten der dasselbe Problem hat wie ich hatte bei der Lösung hilft ;-)

     

    Nochmals ein grooooooooooßes DANKE! für Eure geniale(n) Hilfe(n) :-)

     


    Grüße, Jochen



    • Als Antwort markiert morfeus3009 Mittwoch, 17. August 2011 08:58
    Mittwoch, 17. August 2011 08:28
  • Hallo Jochen,

    Du hast auf mein Posting nicht geantwortet.
    Deine Methode: FindFirstDeviceByCaption ist am effektivsten durch die in diesem Posting angegebene zu ersetzen. 


    ciao Frank
    Mittwoch, 17. August 2011 09:11
  • Hallo Jochen,

    Du hast auf mein Posting nicht geantwortet.
    Deine Methode: FindFirstDeviceByCaption ist am effektivsten durch die in diesem Posting angegebene zu ersetzen. 


    ciao Frank

    Sorry Frank!

    Hatte ich echt vergessen...

    Ich hab´s hier aufm Rechner und auch schon eingebunden, aber noch nicht weiter verfolgt, da es mit dem "alten" Code funktioniert und ich erstmal weitere Baustellen schließen möchte.

    Und dann muß ich nach meinem Urlaub (dann sind wir in der Firma wieder vollständig) die Kollegen davon überzeugen, daß wir C# 2010 zum neuen Standard erklären

    ;-)

    Und da ich das Prog eh nicht davor fertig bekomme (ist zu viel und Infos gibts grad wegen Urlaub vom Kunden wenig)  konzetriere ich mich erstmal darauf daß es funktioniert und die Feinheiten mach ich dann danach...das Finetuning ;-)

    Aber wie gesagt, vergessen isses nicht und wird auch noch verwendet werden :-)

    Den Code kann ich dann ja noch aktualisieren, damit auch andere so ein Prob lösen können und dann haben auch die gleich 2 mögliche Wege, denn wie gesagt bei mir läuft´s und das auch noch echt schnell.

     

    btw.: haste dir das hier schon angeschaut ( COM-Schnittstelle )? Das bringt mich grad richtig in Rage...weil vom Prinzip her geht´s :-(


    Grüße, Jochen
    Mittwoch, 17. August 2011 11:21
  • Hallo Jochen,

    ja, wie gesagt, VS 2010 ist nicht Voraussetzung dafür, aber es ist - wie ich und ja Stefan ja bereits erwähnt hatten - insgesamt deutlich vorteilhafter mit VS 2010 zu entwickeln.

    Aber wenn Du es ist nicht vergisst, hier nochmal die effiziente und typsichere Lösung zu prüfen, ist es ja auch ok. Es ist ein wenig schade für andere, denen die Lösung so ggf. nicht auffällt, weil sie nicht als Antwort abgehakt ist - aber lass Dir da ruhig Zeit.

    Bzgl. der COM-Schnittstelle hatte ich mal reingeschaut, aber ich würde den Vorschlag von Robert folgen und auf Skydrive ein Beispiel-Projekt zur Verfügung stellen. So ist zuviel im Unklaren, weshalb ich da auch nicht geantwortet habe - aber das sollte in dem zugehörigen Thread besprochen werden, nicht hier.

    Dann einen schönen und sonnigen Urlaub! 


    ciao Frank

    Mittwoch, 17. August 2011 12:02
  • Hallo Jochen,

    ja, wie gesagt, VS 2010 ist nicht Voraussetzung dafür, aber es ist - wie ich und ja Stefan ja bereits erwähnt hatten - insgesamt deutlich vorteilhafter mit VS 2010 zu entwickeln.

    Aber wenn Du es ist nicht vergisst, hier nochmal die effiziente und typsichere Lösung zu prüfen, ist es ja auch ok. Es ist ein wenig schade für andere, denen die Lösung so ggf. nicht auffällt, weil sie nicht als Antwort abgehakt ist - aber lass Dir da ruhig Zeit.

    Bzgl. der COM-Schnittstelle hatte ich mal reingeschaut, aber ich würde den Vorschlag von Robert folgen und auf Skydrive ein Beispiel-Projekt zur Verfügung stellen. So ist zuviel im Unklaren, weshalb ich da auch nicht geantwortet habe - aber das sollte in dem zugehörigen Thread besprochen werden, nicht hier.

    Dann einen schönen und sonnigen Urlaub! 


    ciao Frank

    Habe deine USBLib eingebunden.

    Es funktioniert aber nicht!

    Gefunden werden zwar die USB-Ports, aber es kommt (egal welches USB-gerät) immer nur "FoundDevice = null" zurück.

    Irgendwie geht das nicht mit dem Namen?

    Mein Aufruf (nur der Code zu deiner USBLib):

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;
    using System.Management;
    using System.IO;
    using System.Collections;
    using USBLib;
    
    
    bool isDeviceFound = FindFirstDeviceByCaption(_device[0].Remove(length-1));
    
    
    public static bool FindFirstDeviceByCaption(string deviceCaption)
      {
      USB.USBDevice usbDevice = USB.FindDeviceByInstanceID(deviceCaption);
      return (usbDevice != null); // gemessene Zeit: 30 Millisekunden, mit WMI: 10 Sekunden
      }
    

     

    Mach ich da was falsch?

     


    Grüße, Jochen

    Donnerstag, 18. August 2011 07:36
  • Hallo Jochen,

    ich habe Deinen Quellcode ja hier (AnsteuerungHP) für Dich veröffentlicht gehabt.
    Nun, da wäre viel zu tun, aber was das Problem hier angeht, füge einmal folgende Methode in die USBLib ein:

     

    static public USBDevice FindDeviceByCaption(string caption)
    {
     USBDevice foundDevice = null;
    
     foreach (USBController Controller in GetHostControllers())
     {
      SearchHubCaption(Controller.GetRootHub(), ref foundDevice, caption);
      if (foundDevice != null)
       break;
     }
     return foundDevice;
    }
    
    private static void SearchHubCaption(USBHub uSBHub, ref USBDevice foundDevice, string caption)
    {
     foreach (USBPort Port in uSBHub.GetPorts())
     {
      if (Port.IsHub)
      {
       // recursive
       SearchHubCaption(Port.GetHub(), ref foundDevice, caption);
      }
      else
      {
       if (Port.IsDeviceConnected)
       {
        USBDevice Device = Port.GetDevice();
        if (Device.DeviceName == caption)
        {
         foundDevice = Device;
         break;
        }
       }
      }
     }
    }
    

     

    _______________________

     

    Rufe die Methode dann so auf:

     

     USB.USBDevice usbDevice = USB.FindDeviceByCaption(device.Trim());
     bool isDeviceFound = (usbDevice != null);
    


    Dann hast Du noch beim Einlesen aus den "USBNamen.txt" vergessen, auch Umlaute zu ermöglichen. Nimm ggf.:

     string[] usbCations = File.ReadAllLines("USB_Namen.txt", Encoding.Default);
     if (usbCations.Length == 0) cmbUSB_Devices.Items.Add("keine Liste vorhanden");
     else cmbUSB_Devices.Items.AddRange(usbCations);
    

     

    Dann - wenn Du Leerzeichen am Ende o.ä. wegnehmen willst nimm Trim().
    Dein Splitting des "USB" ist sehr "gefährlich" und liefert z.T. falsche Ergebnisse.
    Debugge das ganz genau, es muss die wirkliche Caption jedenfalls in der Methode FindDeviceByCaption "ankommen" und gesucht werden.

    ___________________________

    BTW: eine weitere gute effizente USB-Library ist:
    http://sourceforge.net/projects/usbviewerincsha/
    mit guter TreeView-Darstellung.
    Sie nutzt übrigens auch die von mir empfohlenen SetupDi**** - Methoden in der anderen USBLib.


    ciao Frank

    • Als Antwort markiert morfeus3009 Donnerstag, 18. August 2011 10:03
    • Tag als Antwort aufgehoben morfeus3009 Donnerstag, 18. August 2011 10:51
    • Als Antwort markiert morfeus3009 Donnerstag, 18. August 2011 10:52
    Donnerstag, 18. August 2011 09:28
  • Alles klar Frank...jetzt geht´s :-)

    Danke Dir...

    Ich werde dann den Post bei Gelegenheit mit dem jetzigen Code aktualisieren, aber da ich keine Verwirrung stiften will und im Projekt ja grad n ziemliches "durcheinander" herrscht, werde ich zuerst eine Codebereinigung durchführen, das wird aber evtl. noch n bisschen dauern, da ich ja wie erwähnt ab kommende Woche Dienstag 2 Wochen im Urlaub bin :-D

     

    Zu dem Punkt mit dem einlesen von Umlauten hab ich noch ne Frage:

    Wo muß das denn in den Code rein?

    (Hab´s noch noch nicht getestet, nur eben das mit dem USB-Device)


    Grüße, Jochen
    Donnerstag, 18. August 2011 09:58
  • Hallo Jochen,

    na, da freu ich mich, dass Du das jetzt geschafft hast.
    Dann hast Du jetzt eine sehr schnelle (performante), einfache und saubere Lösung.

    ______________

    • Zu dem Punkt mit dem einlesen von Umlauten hab ich noch ne Frage:
      Wo muß das denn in den Code rein?

    dort, wo Du in Form1.cs folgendes stehen hast:

     datei2 = File.OpenText("USB_Namen.txt");
    

    und da den ganzen Block ersetzen [von StreamReader bis Close()];

     


    ciao Frank

    Donnerstag, 18. August 2011 10:21
  • Hallo,

    auch ich interessiere mich für dieses Thema, deshalb aktiviere ich diesen Post mal wieder :)

    Frank, ich habe deine Lösung mal genommen, funktioniert wirklich gut :) Ich würde dies allerdings gern als Polling while Schleife machen, sprich, wenn sich formx öffnet, soll gepollt werden, ob einer der eingetragen USB_VID's vorhanden ist und das solange tun, bis etwas angesteckt wurde. Wie sehe der Schleifenkopf aus? also while ()... weiß nicht was ich eintragen muss.

    Wäre es auch möglich, eine Verbindung mit dem Gerät aufzubauen, und z.B. eine Txt Datei zu schicken? Aber dazu vielleicht später mehr, erstmal möchte ich das Polling schaffen, sowie eine Verbindung herstellen.

    Gruß

    Freitag, 16. September 2011 10:05
  • Hallo A.,

    schön, daß Dir meine Lösung bei Dir so gut funktioniert.
    GGf. kannst Du dann auch meine als Antwort markierte Lösung als "hilfreich" bewerten.
    Stelle die Frage bitte in einen neuen Thread, weil das hier (meiner Ansicht nach) sonst zu undurchsichtig wird.

     


    ciao Frank
    Freitag, 16. September 2011 11:58
  • Hallo Robert,

    Du hast hier einen Beitrag als Antwort markiert, der offensichtlich nur einen Verweis auf Franks Beitrag effiziente und typsichere Lösung enthält.

    Wenn Du der Meinung bist, dass der Beitrag auf den verwiesen wird, die Antwort auf Jochens Frage ist, markiere diesen bitte als Antwort und hebe die Markierung dieses Beitrags auf.

    Edit: Ich habe diese Änderungen nun selber vorgenommen.

    Danke
    Marcel


    Dienstag, 20. September 2011 11:36
    Moderator