USB Geräte auflisten

TDO88

Bekanntes Mitglied
Hallo Zusammen,
ich benötige eine Auflistung aller angeschlossenen USB Geräte. Ich möchte damit erkennen, welche Kamera (Am Besten DeviceString oder so) angeschlossen ist, damit ich kamerabasierend verschiedene Einstellungen treffen kann.

Ich habe jetzt schon mehrere Sachen aus Google ausprobiert, welche leider alle so nicht funktioniert haben.

Häufig gefundenes Beispiel:
Java:
import java.util.*;
import javax.usb.*;

public class USBLister {

  public static void main(String[] args) throws UsbException {
    //Get UsbHub
    UsbServices services = UsbHostManager.getUsbServices();
    UsbHub root = services.getRootUsbHub();

    listPeripherique(root);
  }

 public static void listPeripherique(UsbHub hub) {
    //List all the USBs attached
    List perepheriques = hub.getAttachedUsbDevices();
    Iterator iterator = perepheriques.iterator();

    while (iterator.hasNext()) {

      UsbDevice perepherique = (UsbDevice) iterator.next();
      System.out.println(perepherique);

      if (perepherique.isUsbHub())
        listPeripherique((UsbHub) perepherique);

    }
  }
}

Problem:
Exception in thread "main" java.lang.NullPointerException
at javax.usb.UsbHostManager.getServicesName(UsbHostManager.java:96)
at javax.usb.UsbHostManager.initialize(UsbHostManager.java:32)
at javax.usb.UsbHostManager.getUsbServices(UsbHostManager.java:24)
at components.USBLister.main(USBLister.java:25)

Ebenso probiert:
Java:
public UsbDevice findDevice(UsbHub hub, short vendorId, short productId)
{
    for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices())
    {
        UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
        if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device;
        if (device.isUsbHub())
        {
            device = findDevice((UsbHub) device, vendorId, productId);
            if (device != null) return device;
        }
    }
    return null;
}

Problem:
Exception in thread "main" java.lang.UnsupportedOperationException: Not supported yet.
at components.USBLister$1.getAttachedUsbDevices(USBLister.java:58)
at components.USBLister.main(USBLister.java:189)

Hat jemand eine Idee, wie die Fehler behoben werden können, bzw. wie ich USB Geräte auflisten oder Kameranamen auslesen kann?
 

TDO88

Bekanntes Mitglied
Hallo Konrad,

vielen Dank für den Hinweis. Das sieht schon mal recht vielversprechend aus.
Allerdings:
Ich habe die
oshi-core-6.2.0.jar
oshi-core-6.2.0-javadoc.jar
oshi-core-6.2.0-sources.jar
eingebunden und diesen kurzen Code ausprobiert:
Java:
public class USBLister
{
    static List<String> oshi = new ArrayList<>();

    public static void main(String[] args)
    {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        printUsbDevices(hal.getUsbDevices(true));
    }
    
    private static void printUsbDevices(List<UsbDevice> list) {
        oshi.add("USB Devices:");
        for (UsbDevice usbDevice : list) {
            oshi.add(String.valueOf(usbDevice));
        }
    }
}

Dabei bekomme ich den Fehler:
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/Guid$GUID
at oshi.hardware.platform.windows.WindowsUsbDevice.<clinit>(WindowsUsbDevice.java:50)
at oshi.hardware.platform.windows.WindowsHardwareAbstractionLayer.getUsbDevices(WindowsHardwareAbstractionLayer.java:96)
at components.USBLister.main(USBLister.java:28)
Caused by: java.lang.ClassNotFoundException: com.sun.jna.platform.win32.Guid$GUID
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 3 more

Leider kann ich damit nicht viel anfangen. Hast du eine Idee, woran das liegen kann? Muss da noch mehr eingebunden werden, als diese 3 jar files?!
 

KonradN

Super-Moderator
Mitarbeiter
Ja, wenn Du Dir die Abhängigkeiten anschaust, dann findest Du unter:

<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>

Also sowohl das jna als auch slf4j werden als Abhängigkeit benötigt.
 

Blender3D

Top Contributor
Hallo Zusammen,
ich benötige eine Auflistung aller angeschlossenen USB Geräte.
Java:
public static Vector<String> getRemoveableDevices() {
        Vector<String> devices = new Vector<String>();
        List<File> files = Arrays.asList(File.listRoots());
        for (File f : files) {
            String displayname = FileSystemView.getFileSystemView().getSystemDisplayName(f).toUpperCase();
            String description = FileSystemView.getFileSystemView().getSystemTypeDescription(f).toLowerCase();
            if (description.endsWith("wechseldatenträger") || description.endsWith("removable device")
                    || description.contains("usb"))
                devices.add(displayname);
        }
        return devices;
 

TDO88

Bekanntes Mitglied
Vielen Dank, das werde ich auch nochmal ausprobieren.
Ich habe jetzt allerdings gerade ein ganz anderes Problem...
Ich habe die slf4j und jna noch hinzugefügt (von jna hatte ich bereits ältere Versionen eingebunden). Hat aber leider auch nichts gebracht.
Aktuell ist der Stand leider, dass die Oberfläche der Anwendung überhaupt nicht mehr startet 🤣
Leider komme ich da gerade auch nicht so wirklich weiter. Code, der gefühlt seit Jahrhunderten funktioniert crasht nun plötzlich.
Bei diesem Aufruf:
aufruf.png
springt mir der Debugger in ein InvocationEvent
InvocationEvent.png

und endet schließlich im EventDispatchThread in einer Endlosschleife...
EventDispatchThread.png
EventDispatchThread2.png

Hat jemand eine Idee, woran das jetzt liegen kann?
Wenn das wieder läuft, kümmere ich mich um das ursprüngliche Problem 🤣

Vielen dank
 

Blender3D

Top Contributor
Leider komme ich da gerade auch nicht so wirklich weiter. Code, der gefühlt seit Jahrhunderten funktioniert crasht nun plötzlich.
Wenn der Code bisher gelaufen ist, solltest Du kürzlich gemachte Änderungen betrachten.
Zur Warnung: Die -g Option weist den Compiler an alle Debugging Infos hineinzupacken.
Der EventDispatchThread darf nur mit Aufgaben die schnell erledigt werden gefüttert werden siehe. https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
Der Fehler sieht aber eher nach einem Listener aus der immer wieder ausgelöst wird.
Java:
setSelectedIndex()
Wird eventuell im Code durch einen Listener ItemStateChanged .. abgefangen und dort wird z.B. wiederum der Index gesetzt ....
 

TDO88

Bekanntes Mitglied
Wenn der Code bisher gelaufen ist, solltest Du kürzlich gemachte Änderungen betrachten.
Habe ich. Ich hatte mir eine eigene Klasse für das ursprüngliche Problem erstellt mit eigener Main Methode, damit ich diese unabhängig vom Rest debuggen kann. Auch diese Klasse habe ich mittlerweile schon komplett gelöscht. Das einzige was sonst geändert wurde, waren .jar files, die ich eingebunden/gelöscht habe.
Z.B. habe ich gesehen, das von Konrad angesprochener jna.jar bereits eine jna.jar, jna-3.4.0.jar und eine jna-3.3.0-platform.jar eingebunden waren. Diese habe ich dann gelöscht um die neueste jna einzubinden. Dann ging nichts mehr.
Habe die anderen auch wieder eingebunden, aber es läuft dennoch nicht.

Zu dem Listener. Der einzige Listener, der auf die ComboBox zugreift, ist der automatisch von NetBeans erzeugte Listener
VideoResolution.png

Das Programm kommt irgendwie nicht mehr aus dieser while Schleife im EventDispatchThread heraus.
 

KonradN

Super-Moderator
Mitarbeiter
Was ist denn diese jComboBox_VideoResolutionActionPerformed Methode? Was machst Du in dieser?

Ist der der Code mit dem Switch evtl. Teil von dieser Methode (direkt oder auch indirekt aufgerufen)?

Generell rennst Du in das beschriebene Problem, wenn Du in dem EVent, das auf auf Veränderungen reagierst wieder etwas an dem Control veränderst.

Und bezüglich Abhängigkeiten: Da solltest Du genau aufpassen, was für Abhängigkeiten benötigt werden. Nicht einfach irgendwas neueres einbinden oder so. Das kann immer zu Problemen führen! Gerade oshi hat eine sehr enge Abhängigkeit zu jni - da kann eine falsche Version der Abhängigkeit durchaus Probleme bereiten (Aber nicht das von Dir beschriebene Problem!).

Generell wäre eh die Empfehlung, Projekte mit Maven oder Gradle zu machen um dann die transitiven Abhängigkeiten automatisch verwaltet zu bekommen.
 

TDO88

Bekanntes Mitglied
Okay, vielen Dank für den Hinweis.

Also in der Methode wird eine Verbindung zur Kamera aufgebaut, mit der in der ComboBox ausgewählten Auflösung.
Diesen Verbindungsaufbau habe ich jetzt auch gedebuggt und bin darauf gestoßen, dass er vermutlich an dieser Codezeile crasht.

Java:
OXYOINST = (OXYODLL) Native.loadLibrary(OxyoDLLPathAndName, OXYODLL.class);

Da wird eine DLL eingebunden, welche lokal auf dem Laufwerk liegt. Die DLL ist auch vorhanden und der Pfad in der Variable stimmt auch. OXYOINST ist ein Objekt der DLL-Klasse.

Dann hat das vermutlich doch mit den eingebundenen .jar files (jna) zu tun. Aber ich habe jetzt alle möglichen Varianten der jna.jars ausprobiert und es will einfach nicht starten.
 

TDO88

Bekanntes Mitglied
Oh mann... ich hänge leider immernoch an diesem Problem.
Das Programm will einfach nicht mehr starten. Hat jemand noch eine Idee, was ich probieren kann?
Ich habe die obige Zeile auch mal auskommentiert und dann läuft das Programm auch weiter, bis es die nächste DLL einbinden will.
Es muss also was mit dem laden der DLLs und dem JNA Paket zusammenhängen oder?
Hat da noch jemand Tipps & Tricks?!
 

KonradN

Super-Moderator
Mitarbeiter
Maven Unterstützung ist in allen großen IDEs integriert, aber das heisst nicht, dass man es auch nutzt. Hast Du denn eine pom.xml in der das Projekt beschrieben wurde? Da Du jar Dateien eingebunden hast, klingt es erst einmal nicht nach einem Maven Projekt.
 

TDO88

Bekanntes Mitglied
Ich habe gerade mal geschaut und: Nein, ich habe keine pom.xml.
Kann ich maven im jetzigen Zustand integrieren und es würde mir evtl. bei der Problembehebung behilflich sein?
Ich habe leider noch keinen Plan von maven und müsste mich da erstmal einlesen
 

KonradN

Super-Moderator
Mitarbeiter
Durch maven würdest Du die Abhängigkeit die Du in Deinem Code brauchst, schlicht angeben und dann würde maven dafür sorgen, dass die benötigten Abhängigkeiten alle in der richtigen Version eingebunden werden. Denn wie gesagt: Ich vermute, dass es da Probleme gibt mit den Versionen der jeweiligen Abhängigkeiten. Aber das ist nur geraten - für eine sichere Aussage fehlen schlicht die Informationen.
 

TDO88

Bekanntes Mitglied
Welche Informationen könnten denn helfen?
Ist es machbar Maven auf mein aktuelles Projekt draufzulegen und diese Abhängigkeiten angezeigt zu bekommen?
 

TDO88

Bekanntes Mitglied
Endlich.... es hat funktioniert. Habe jetzt offensichtlich die richtige Kombination der eingebundenen jars gefunden und das Programm startet wieder.
Dann schaue ich mir jetzt mal maven an und kümmere mich um mein ursprüngliches Problem.
Vielen Dank bis dahin
 

TDO88

Bekanntes Mitglied
Soo... update:
Ich versuche jetzt gerade wieder mit Hilfe von oshi die USB Geräte auszulesen, mit dem Beispiel aus dem vorherigen Post.
Java:
public class USBLister
{
    static List<String> oshi = new ArrayList<>();

    public static void main(String[] args)
    {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        printUsbDevices(hal.getUsbDevices(true));
    }
   
    private static void printUsbDevices(List<UsbDevice> list) {
        oshi.add("USB Devices:");
        for (UsbDevice usbDevice : list) {
            oshi.add(String.valueOf(usbDevice));
        }
    }
}

Ich habe dazu die jna-5.12.1 + jna-platform-5.12.1 und slf4j.
Zusätzlich habe ich die jna-3.3.0 eingebunden, da ich diese für die DLLs benötige. Daher der ganze Zirkus vorher.
Jetzt bekam ich den Fehler:
Exception in thread "main" java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;Ljava/util/Map;)Lcom/sun/jna/Library;

Laut meiner Recherche liegt es vermutlich daran, dass die Software die alte jna Version benutzt, welche die load Methode noch nicht unterstützt.

Also habe ich habe die alte Version mal testweise entfernt. Bringt mir bei dem Code Ausschnitt von oben aber die Fehlermeldung:
java.lang.UnsatisfiedLinkError: Can't obtain static newInstance method for class com.sun.jna.Structure

Mit dieser Fehlermeldung komme ich jetzt nicht wirklich weiter. Zudem mein anderer Code wieder in diese blöde Endlosschleife läuft, sobald die alte jna aus dem Projekt entfernt wurde.
Dachte es liegt daran, weil die Methode Native.loadLibrary mittlerweile veraltet ist. Habe den Aufruf geändert in Native.load(...), führt aber zum selben Resultat... ich hänge in der Endlosschleife.

Ist es möglich mehrere Versionen einer Library einzubinden und bei den Aufrufen die jeweilige Version aufzurufen? Oder hat jemand eine noch bessere Idee, wie man beide Probleme unter einen Hut bekommt?
 

TDO88

Bekanntes Mitglied
Oder ich vereinfache möglicherweise die Anforderung.
Wie kann ich den Namen meiner angeschlossenen WebCam bzw. Kamera abfragen?
 

KonradN

Super-Moderator
Mitarbeiter
Also meine Lösung um die Geräte aufzulisten, wäre einfach:


Der Code ist einfach nur:

Java:
package de.kneitzel;

import org.junit.jupiter.api.Test;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.UsbDevice;

import java.util.List;

public class ListUSBTests {
    @Test
    public void testListAllUSBDevices() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();

        // In Struktur darstellen / ermitteln
        List<UsbDevice> devices =  hal.getUsbDevices(true);
        for (UsbDevice device: devices) {
            System.out.println(device);
        }

        List<UsbDevice> allDevices = hal.getUsbDevices(false);

        for (UsbDevice device: allDevices) {
            System.out.println(device.getName() + " (" + device.getVendor() + " / " + device.getVendor() + ":" + device.getProductId() + ")");
        }
    }
}

In der POM nur einfach:
XML:
        <dependency>
            <groupId>com.github.oshi</groupId>
            <artifactId>oshi-core</artifactId>
            <version>${oshi.version}</version>
        </dependency>

mit der Property:
<oshi.version>6.2.1</oshi.version>

Wäre das eine Idee? Oder was brauchst Du genau?
 

TDO88

Bekanntes Mitglied
Vielen Dank für deine Mühe Konrad.
Ich habe nur leider bei dem oshi Paket das Problem, dass ich eine neuere jna Version brauche. Mein Programm hat bisher die Version 3.3.0 eingebunden. Damit funktioniert aber das oshi Paket nicht.
Wenn ich die neue jna einbinde, funktioniert das einbinden der DLLs nicht mehr. Dann hänge ich wieder in der oben beschriebenen Endlosschleife.

Kann ich bei den Methodenaufrufen oder auch Klassenweise auswählen, welche Version einer Lib ich verwenden möchte?
 

TDO88

Bekanntes Mitglied
Ja, eben. Oshi arbeitet mit jna 5.12.1.
Der Rest des Programmes, an dem ich dran bin arbeitet mit 3.3.0. Wenn ich 5.12.1 einbinde funktioniert der Rest nicht mehr.
Vielleicht war das nicht so richtig verständlich von mir ausgedrückt. Hoffe es wird jetzt klar
 

KonradN

Super-Moderator
Mitarbeiter
Der Rest des Programmes, an dem ich dran bin arbeitet mit 3.3.0.
JNA 3.3.0? Das ist extrem alt. die 4.0.0 war 2013! Hast Du da mal geschaut, ob man da nicht auf eine neue Version wechseln kann bzw. was da überhaupt benutzt wird.

Hoffe es wird jetzt klar
Ja, jetzt ist es klar geworden. Aber da ist es schwer, irgendwas zu sagen. Sowas kann generell immer zu Problemen führen fürchte ich.

Workarounds könnte man sich überlegen, aber die sind alle nicht sauber. Man kann z.B. schauen, ob man das irgendwie kapseln kann. Das Einfachste ist halt in einen eigenen Prozess. Dann ruft ein Programm halt ein anderes auf. Ohne zu wissen, was da gemacht wird - das könnte halt ein eigenes Programm sein welches dann vom anderen Programm aufgerufen wird. Oder anders herum ein Aufruf, um die USB Geräte zu listen.

Aber das sind wirkliche Workarounds. Sowas würde ich nicht machen wollen.
 

TDO88

Bekanntes Mitglied
Das wurde damals von einem Kollegen eingebunden.
Wir benutzen die alte Version um DLLs einzubinden und zu benutzen mit der Methode Native.loadLibraray(...).
Diese ist ja mittlerweile veraltet und durch Native.load(...) ersetzt worden.
Ich habe dann auch mal versucht die Native.loadLibrary durch durch die Native.load Methode und der jna5.12.1 Version zu ersetzen, aber dabei bin ich immer wieder in die oben schon beschriebene Endlosschleife geraten.

Ich denke der von dir beschriebene Workaround klingt wirklich leider nicht so spaßig ;)

P.s. Ich habe mir gerade mal dein Youtube Video "JavaFx Maven Projekt aus bestehendem Projekt" angeschaut. Finde es sehr gut erklärt und ich werde demnächst versuchen meine Projekte nach Maven umzuziehen. ✌️
 

Ähnliche Java Themen

Neue Themen


Oben