Manage USB-Drives per devcon.exe

    • Offizieller Beitrag

    Hi,
    es wurde ja schon in einigen Threads auf das Tool devcon hingewiesen. Ich habe mal alle Beschreibungen zu den einzelnen Befehlen zusammengefaßt. Hier findet ihr die Syntaxbeschreibung.
    Nicht wundern, dass ein Scan recht lange dauert. Als Trigger verwende ich die durch die Hardwareerkennung gestartete rundll32.exe. Erst wenn diese beendet wurde, wird die Liste neu geschrieben.

    Edit: Habe die Zuordnung der Hardware-ID geändert. Nun ist gesichert, dass bei Sticks mit identischer Bezeichnung auch die ID zum Laufwerk stimmt.

    Edit: Da ich ständig am Laptop arbeite, war mir der Fehler mit der Floppy gar nicht bewußt geworden. :D
    Ich überprüfe im Registryeintrag auf $pref = _StringBetween($val, 'Media#', '&RM#', 1). Nur bei USB-Speichermedien ist dieser String in der Kennung enthalten. Jetzt habe ich dahinter eine Fehlerabfrage gesetzt mit ContinueLoop im Fehlerfall. Damit sollte eigentlich die Floppy keine Probleme mehr machen.
    Über weiteres Feedback bin ich natürlich erfreut. ;)

    Bsp. zum Managen von USB-Drives
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <String.au3>
    #include <Constants.au3>
    #include <Array.au3>
    Opt('GUIOnEventMode', 1)
    Global $path_Devcon = @MyDocumentsDir & '\DOWNLOADS\TOOLS\Devcon\i386\devcon.exe' ; <<===== Pfad anpassen
    Global $aRemovable, $strRun

    [/autoit] [autoit][/autoit] [autoit]

    $gui = GUICreate('Manage USB-Drive', 500, 120)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_ende')
    $hListView = GUICtrlCreateListView('Laufwerk|Bezeichnung', 10, 10, 350, 100)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 60)
    _GUICtrlListView_SetColumnWidth($hListView, 1, $LVSCW_AUTOSIZE_USEHEADER )
    $btRemove = GUICtrlCreateButton('Entfernen', 380, 10, 100, 20)
    GUICtrlSetOnEvent(-1, '_entfernen')
    $btScan = GUICtrlCreateButton('Scan', 380, 40, 100, 20)
    GUICtrlSetOnEvent(-1, '_scan')

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    _LVwrite()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _ende()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _setStat($disable=True)
    Local $stat = $GUI_ENABLE
    If $disable Then $stat = $GUI_DISABLE
    GUICtrlSetState($btRemove, $stat)
    GUICtrlSetState($btScan, $stat)
    EndFunc ;==>_setStat

    [/autoit] [autoit][/autoit] [autoit]

    Func _RunDevcon($strRun)
    Local $data, $foo = Run("cmd.exe", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
    StdinWrite($foo, $strRun & @CRLF)
    StdinWrite($foo)
    While True
    $data &= StdoutRead($foo)
    If @error Then ExitLoop
    Sleep(25)
    WEnd
    Local $split = StringSplit($data, @LF)
    $data = ''
    For $i = 5 To $split[0]
    If StringStripWS($split[$i], 8) == '' Then ExitLoop
    $data &= $split[$i]
    Next
    Return $data
    EndFunc ;==>_RunDevcon

    [/autoit] [autoit][/autoit] [autoit]

    Func _LVwrite()
    $aRemovable = _GetRemovable()
    If Not $aRemovable[0][0] Then Return
    For $i = 0 To UBound($aRemovable) -1
    GUICtrlCreateListViewItem($aRemovable[$i][0] & '|' & $aRemovable[$i][1], $hListView)
    Next
    EndFunc ;==>_LVwrite

    [/autoit] [autoit][/autoit] [autoit]

    Func _entfernen()
    _setStat()
    Local $index = _GUICtrlListView_GetSelectedIndices($hListView)
    If $index = '' Then
    _setStat(False)
    Return
    EndIf
    Local $indRemove = _ArraySearch($aRemovable, _GUICtrlListView_GetItemText(GUICtrlGetHandle($hListView), $index, 1),0,0,0,0,1,1)
    _GUICtrlListView_DeleteAllItems($hListView)
    WinSetTitle($gui, '', 'Laufwerk wird entfernt..')
    _Remove($aRemovable[$indRemove][2])
    WinSetTitle($gui, '', 'Laufwerk wurde entfernt')
    _LVwrite()
    Sleep(500)
    WinSetTitle($gui, '', 'Manage USB-Drive')
    _setStat(False)
    EndFunc ;==>_entfernen

    [/autoit] [autoit][/autoit] [autoit]

    Func _scan()
    _setStat()
    Local $count1 = 0, $count2 = 0, $list1 = ProcessList('rundll32.exe')
    If Not @error Then $count1 = $list1[0][0]
    _GUICtrlListView_DeleteAllItems($hListView)
    WinSetTitle($gui, '', 'Es wird gescannt..')
    $strRun = '"' & $path_Devcon & '" rescan'
    _RunDevcon($strRun)
    $list2 = ProcessList('rundll32.exe')
    If Not @error Then $count2 = $list2[0][0]
    If $count2 > $count1 And $count1 = 0 Then
    Do
    Sleep(50)
    Until Not ProcessExists($list2[1][0])
    ElseIf $count2 > $count1 Then
    For $i = 1 To UBound($list2) -1
    If _ArraySearch($list1, $list2[$i][0]) = -1 Then
    Do
    Sleep(50)
    Until Not ProcessExists($list2[$i][0])
    ExitLoop
    EndIf
    Next
    EndIf
    WinSetTitle($gui, '', 'Scan beendet')
    _LVwrite()
    Sleep(500)
    WinSetTitle($gui, '', 'Manage USB-Drive')
    _setStat(False)
    EndFunc ;==>_scan

    [/autoit] [autoit][/autoit] [autoit]

    Func _Remove($ID)
    $strRun = '"' & $path_Devcon & '" remove ' & $ID
    _RunDevcon($strRun)
    EndFunc ;==>_Remove

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetRemovable()
    Local $reg, $tmp, $val, $pref, $aDrive[1][3]
    Local $var = DriveGetDrive( "REMOVABLE" )
    If Not @error Then
    For $i = 1 To UBound($var) -1
    $val = ''
    $reg = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices", "\DosDevices\" & $var[$i])
    For $k = 1 To StringLen($reg) - 2 Step 2
    $tmp = _HexToString(StringMid($reg, $k, 2))
    If $tmp <> "" Then
    $val = $val & $tmp
    EndIf
    Next
    $pref = _StringBetween($val, 'Media#', '&RM#', 1)
    If @error Then ContinueLoop
    If $aDrive[UBound($aDrive)-1][0] <> '' Then ReDim $aDrive[UBound($aDrive)+1][3]
    $aDrive[UBound($aDrive)-1][0] = StringUpper($var[$i])
    $tmp = _GetUSBCaption($pref[0])
    $tmp = StringSplit($tmp, '|')
    $aDrive[UBound($aDrive)-1][1] = $tmp[1]
    $tmp = StringSplit($tmp[2], @LF)
    $aDrive[UBound($aDrive)-1][2] = $tmp[1]
    Next
    EndIf
    Return $aDrive
    EndFunc ;==>_GetRemovable

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetUSBCaption($strIDPrefix)
    Local $aUSB[1]=[0], $i = 0, $k, $var, $sub, $sRet
    While 1
    $i += 1
    $var = RegEnumKey('HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR', $i)
    If Not @error Then
    $k = 0
    While 1
    $k += 1
    $sub = RegEnumKey('HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR\' & $var, $k)
    If Not @error Then
    ReDim $aUSB[UBound($aUSB)+1]
    $aUSB[UBound($aUSB)-1] = $var & '\' & $sub
    Else
    ExitLoop
    EndIf
    WEnd
    Else
    ExitLoop
    EndIf
    WEnd
    For $i = 1 To UBound($aUSB) -1
    $var = RegRead('HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR\' & $aUSB[$i], 'ParentIdPrefix')
    If Not @error Then
    If $var = $strIDPrefix Then
    $sRet = RegRead('HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR\' & $aUSB[$i], 'FriendlyName')
    Return $sRet & '|' & RegRead('HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR\' & $aUSB[$i], 'HardwareID')
    EndIf
    EndIf
    Next
    EndFunc ;==>_GetUSBCaption

    [/autoit]
    einige Funktionsbsp.
    [autoit]

    #include <Constants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Local $path_Devcon = @MyDocumentsDir & '\DOWNLOADS\TOOLS\Devcon\i386\devcon.exe' ; <<===== Pfad anpassen
    Local $strRun, $ID

    [/autoit] [autoit][/autoit] [autoit]

    ; Name und Hardware-ID der Instance-ID USB ausgeben
    $strRun = '"' & $path_Devcon & '" hwids *USB*'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)
    ; mögliche Ausgabe:
    ; USB\VID_13FE&PID_1D00\907310000250
    ; Name: USB-Massenspeichergerät
    ; Hardware ID's:
    ; USB\Vid_13fe&Pid_1d00&Rev_0110
    ; USB\Vid_13fe&Pid_1d00
    ; Compatible ID's:
    ; USB\Class_08&SubClass_06&Prot_50
    ; USB\Class_08&SubClass_06
    ; USB\Class_08

    ; Entfernen des USB-Massenspeichers mit der ID "USB\Vid_13fe&Pid_1d00&Rev_0110"
    #cs
    $ID = '"USB\Vid_13fe&Pid_1d00&Rev_0110"' ; <<------- ID in Anführungszeichen einfassen, sonst Fehler in Console
    $strRun = '"' & $path_Devcon & '" remove ' & $ID
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)
    #ce
    ; Scannen nach neu angeschlossener Hardware, z.B. wieder Aktivieren eines zuvor entfernten USB-Sticks
    $strRun = '"' & $path_Devcon & '" rescan'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; alle PCI-Geräte auf dem Computer ausgeben
    $strRunRun = '"' & $path_Devcon & '" -m:\\' & @ComputerName & ' find pci\*'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzeigen aller bekannten Setupklassen
    $strRun = '"' & $path_Devcon & '" classes'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzeigen von Dateien, die jeweils mit den in der Setupklasse ports (Anschlüsse) enthaltenen
    ; Geräten verknüpft sind
    $strRun = '"' & $path_Devcon & '" driverfiles =ports'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzeigen der Geräteinstanzen aller Geräte , die auf dem lokalen Computer vorhanden sind.
    $strRun = '"' & $path_Devcon & '" find *'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzeigen aller "nicht vorhandenen" Geräte und vorhandenen Geräte der Klasse ports (Anschlüsse).
    ; Dies schließt auch Geräte ein, die entfernt wurden, Geräte die von einem Steckplatz zu einem anderen
    ; Steckplatz versetzt wurden, und möglicherweise auch Geräte, die aufgrund einer BIOS-Änderung anders
    ; aufgezählt wurden.
    $strRun = '"' & $path_Devcon & '" findall =ports'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzeigen aller vorhandenen Geräte aller angegebenen Klassen (in diesem Fall der Klassen "USB" und "1394").
    $strRun = '"' & $path_Devcon & '" listclass usb 1394'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzeigen der Ressourcen, die von den Geräten der Setupklasse USB verwendet werden.
    $strRun = '"' & $path_Devcon & '" resources =usb'
    ConsoleWrite(_RunDevcon($strRun) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Func _RunDevcon($strRun)
    Local $data, $foo = Run("cmd.exe", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
    StdinWrite($foo, $strRun & @CRLF)
    StdinWrite($foo)
    While True
    $data &= StdoutRead($foo)
    If @error Then ExitLoop
    Sleep(25)
    WEnd
    Local $split = StringSplit($data, @LF)
    $data = ''
    For $i = 5 To $split[0]
    If StringStripWS($split[$i], 8) == '' Then ExitLoop
    $data &= $split[$i]
    Next
    Return $data
    EndFunc

    [/autoit]

    DL bisher: 14

  • Hallo BugFix.

    Ich bekomme folgende Fehlermeldung beim Versuch die GUI zu öffnen:

    Spoiler anzeigen
    [autoit]


    C:\AHL\Laptop\ManageUSB.au3 (158) : ==> Subscript used with non-Array variable.:
    $aDrive[UBound($aDrive)-1][1] = _GetUSBCaption($pref[0])
    $aDrive[UBound($aDrive)-1][1] = _GetUSBCaption($pref^ ERROR

    [/autoit]


    $path_Devcon wurde na klar angepaßt ;)

    LG,
    Lina.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    Einmal editiert, zuletzt von Alina (8. Februar 2009 um 02:17)

    • Offizieller Beitrag

    Hi Alina,
    grrr.. Schönheitsfehler. Da hab ich die Variablendeklaration innerhalb der Funktion an die falsche Zeile gesetzt. Einfach die ersten beiden Zeilen der Funktion tauschen, dann sollte es klappen.

    Geänderte Version hochgeladen, dieser Fehler sollte damit auch behoben sein.

  • Habe den gleichen Fehler wie Alina. Muss dazu sagen: Bei mir läuft noch AutoIt 3.2.10.0.
    Aber damit scheint es nichts zu tun zu haben.

    Sondern das Auslesen der Registry gibt nichts brauchbares zurück.
    Die Variable $val hat bei mir in Zeile 131 folgenden Inhalt:
    '\??\FDC#GENERIC_FLOPPY_DRIVE#5&2ded1349&0&0#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}'

    Damit gibts das StringBetween anschließend keine Array zurück.
    Denn die Strings 'Media#' und '&RM#' sind ja nicht enthalten.

    Edit: Es ist der erste Schleifendurchlauf, wo es mein Floppy-LW A findet !

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    • Offizieller Beitrag

    Hmm, eigentlich wird beim Einstecken eines eines USB-Devices ein Registryeintrag in HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR\ erstellt (und nicht wieder entfernt), mit den Parametern des Devices.
    autoit.de/wcf/attachment/3888/ autoit.de/wcf/attachment/3889/

    Probiert mal bitte mit dem WMI-Code von hier: [ gelöst ] USB-Hardware-ID auslesen
    Sollte bei eingestecktem Stick in etwa so etwas herauskommen:

    Code
    \\ComputerName\root\cimv2:Win32_PnPEntity.DeviceID="USBSTOR\\DISK&VEN_USB&PROD_FLASH_DISK&REV_V1.1\\907310000250&0"

    Wenn nicht... :wacko:

  • Vielleicht habe ich mich nicht verständlich genug ausgedrückt.

    Dein Script sammelt in Zeile 120 'REMOVEABLE' Drives, dazu zählen bei mir auch Floppy A und eine virtuelle Floppy B.
    Nun durchläuft das Script das Array ( Zeilen 122-139) und steigt gleich bei Floppy A aus weil das StringBetween kein gültiges Array liefert.
    Ändere ich die For-Schleife ab (Zeile 122: For $i = 3 ...) dann scheint es auch bei mir zu laufen.

    Gruß
    micha_he

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Also nun bekomme ich folgenden Fehlen:

    E:\ManageUSB.au3 (134) : ==> Subscript used with non-Array variable.:
    $tmp = _GetUSBCaption($pref[0])
    $tmp = _GetUSBCaption($pref^ ERROR


    Mhhhhhhh.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    • Offizieller Beitrag

    Achja, die gute (böse) alte Floppy.
    OK, Änderung wie folgt:

    Spoiler anzeigen
    [autoit]

    Func _GetRemovable()
    Local $reg, $tmp, $val, $pref, $aDrive[1][3]
    Local $var = DriveGetDrive( "REMOVABLE" )
    If Not @error Then
    For $i = 1 To UBound($var) -1
    $val = ''
    $reg = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices", "\DosDevices\" & $var[$i])
    For $k = 1 To StringLen($reg) - 2 Step 2
    $tmp = _HexToString(StringMid($reg, $k, 2))
    If $tmp <> "" Then
    $val = $val & $tmp
    EndIf
    Next
    $pref = _StringBetween($val, 'Media#', '&RM#', 1)
    If @error Then ContinueLoop ; <========================= DIESE ZEILE EINFÜGEN !!!
    If $aDrive[UBound($aDrive)-1][0] <> '' Then ReDim $aDrive[UBound($aDrive)+1][3]
    $aDrive[UBound($aDrive)-1][0] = StringUpper($var[$i])
    $tmp = _GetUSBCaption($pref[0])
    $tmp = StringSplit($tmp, '|')
    $aDrive[UBound($aDrive)-1][1] = $tmp[1]
    $tmp = StringSplit($tmp[2], @LF)
    $aDrive[UBound($aDrive)-1][2] = $tmp[1]
    Next
    EndIf
    Return $aDrive
    EndFunc ;==>_GetRemovable

    [/autoit]


    Ich werde es gleich mal im ersten Post korrigieren.

    • Offizieller Beitrag

    Auch nach deinen ganzen änderungen kommt diese Fehlermeldung :
    C:\Users\Michael\Desktop\rt.au3 (134) : ==> Subscript used with non-Array variable.:
    $tmp = _GetUSBCaption($pref[0])
    $tmp = _GetUSBCaption($pref^ ERROR

  • Der Start des Tools geht jetzt und wenn ein USB-Stick vorhanden ist, wird er auch angezeigt.

    Klicke ich jetzt nochmal auf Scan kommte folgende Meldung:
    autoit.de/wcf/attachment/3893/

    Wähle ich dagegen meinen USB-Stick aus und klicke auf Entfernen, erscheint folgender Fehler:
    autoit.de/wcf/attachment/3894/

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    • Offizieller Beitrag


    Wähle ich dagegen meinen USB-Stick aus und klicke auf Entfernen, erscheint folgender Fehler:


    Kann es sein, dass du nicht die aktuelle Stable-Version hast? Die _ArraySearch-Funktion wurde nämlich verändert und hat jetzt einen Parameter mehr.

    Auch nach deinen ganzen änderungen kommt diese Fehlermeldung :
    C:\Users\Michael\Desktop\rt.au3 (134) : ==> Subscript used with non-Array variable.:
    $tmp = _GetUSBCaption($pref[0])
    $tmp = _GetUSBCaption($pref^ ERROR


    Raupi, sicher dass If @error Then ExitLoop eingefügt ist? Denn in diesem Fall wird $pref[0] gar nicht zur Verarbeitung herangezogen.

    Edit: In Post 1 ist der Code (auch im Anhang) jetzt aktualisiert.

    • Offizieller Beitrag
    Zitat

    Raupi, sicher dass If @error Then ExitLoop eingefügt ist? Denn in diesem Fall wird $pref[0] gar nicht zur Verarbeitung herangezogen.

    Habe nix eingefügt , da ich mich darauf verlassen habe :

    Zitat

    Ich werde es gleich mal im ersten Post korrigieren.


    Hast du ja jetzt gemacht ;)

  • Also mit der NUN oberen Version arbeitet es einwandfrei !!!

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Funktioniert. Nun habe ich noch ein Problem :)

    Was soll passieren wenn ich auf "Entfernen" klicke? ^^

  • Was soll passieren wenn ich auf "Entfernen" klicke? ^^

    Kann wird das USB Gerät abgemeldet (Sicheres entfernen der Hardware).
    Schau einfach vorher und nach dem betätigen des Buttons "Entfernen" mal im Autoplatz nach dem entsprechenden Laufwerk. Nach dem betätigen ist es weg.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Hi

    Hier ist meine Version.
    Die Erkennung erfolgt ausschließlich über wmi, also bin ich nicht auf die Registry angewiesen...
    Andererseits dauert die Auflistung doch erheblich länger.

    Für Devcon verwende ich die InstanceID.

    BugFix :
    1) Hast du 2 Identische Sticks? Ich kann meine Version leider nicht testen, ob das dann auch funktioniert...
    2)was passiert mit deiner Methode, wenn du manuell im Gerätemanager deaktivierst und dann per DevCon aktivierst?
    Bei mir (mitder InstanceID) sagt Devcon zwar, daß es geklappt hat, ist aber deinitiv nicht so!?
    Thx

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <ProgressConstants.au3>
    #include <Constants.au3>
    Opt("MustDeclareVars", 1)
    Opt("GuiOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $Devcon = @ScriptDir & "\Devcon.exe"

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui, $hListView, $hProgress, $hDummyS, $hDummyE
    Global $aUSBDRIVES, $iPGCnt = 0, $B_DESCENDING

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("USB Test", 500, 210)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
    $hListView = GUICtrlCreateListView("#|Name|State|InstanceID", 10, 10, 350, 170, 0)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 20)
    _GUICtrlListView_SetColumnWidth($hListView, 1, 250)
    _GUICtrlListView_SetColumnWidth($hListView, 2, 75)
    _GUICtrlListView_SetColumnWidth($hListView, 3, 400)
    $hDummyS = GUICtrlCreateDummy()
    GUICtrlCreateButton("Remove", 370, 10, 120, 20)
    GUICtrlSetOnEvent(-1, "_REMOVE")
    GUICtrlCreateButton("Restart", 370, 40, 120, 20)
    GUICtrlSetOnEvent(-1, "_RESTART")
    GUICtrlCreateButton("Enable", 370, 70, 120, 20)
    GUICtrlSetOnEvent(-1, "_ENABLE")
    GUICtrlCreateButton("Disable", 370, 100, 120, 20)
    GUICtrlSetOnEvent(-1, "_DISABLE")
    GUICtrlCreateButton("Scan", 370, 130, 120, 20)
    GUICtrlSetOnEvent(-1, "_SCAN")
    GUICtrlCreateButton("Update List", 370, 160, 120, 20)
    GUICtrlSetOnEvent(-1, "_UPDATE")
    $hDummyE = GUICtrlCreateDummy()
    $hProgress = GUICtrlCreateProgress(10, 190, 480, 10)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _UPDATE()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _ButtonState($State = $GUI_ENABLE)
    For $i = $hDummyS To $hDummyE
    GUICtrlSetState($i, $State)
    Next
    GUICtrlSetState($hListView, $GUI_FOCUS)
    EndFunc ;==>_ButtonState

    [/autoit] [autoit][/autoit] [autoit]

    Func _Progress()
    $iPGCnt += 20
    If $iPGCnt > 100 Then $iPGCnt = 0
    GUICtrlSetData($hProgress, $iPGCnt)
    EndFunc ;==>_Progress

    [/autoit] [autoit][/autoit] [autoit]

    Func _DevCon($Cmd)
    _ButtonState($GUI_DISABLE)
    Local $aSel = _GUICtrlListView_GetSelectedIndices($hListView, True), $PID, $sStdOut
    GUICtrlSetStyle($hProgress, $PBS_MARQUEE)
    $iPGCnt = 0
    AdlibEnable("_Progress", 10)
    For $i = 1 To $aSel[0]
    $PID = Run($Devcon & " " & $Cmd & " " & _GUICtrlListView_GetItemText($hListView, $aSel[$i], 3), "", @SW_HIDE, $STDOUT_CHILD)
    $sStdOut = ""
    While 1
    $sStdOut &= StdoutRead($PID)
    If @error Then ExitLoop
    WEnd
    ProcessWaitClose($PID)
    If StringInStr($sStdOut, "No matching device") Then ContinueLoop
    If $Cmd = "remove" Then _GUICtrlListView_DeleteItem(GUICtrlGetHandle($hListView), $aSel[$i])
    If $Cmd = "disable" Then _GUICtrlListView_SetItemText($hListView, $aSel[$i], "DISABLED", 2)
    If $Cmd = "enable" Then _GUICtrlListView_SetItemText($hListView, $aSel[$i], "ENABLED", 2)
    Next
    AdlibDisable()
    GUICtrlSetStyle($hProgress, 0)
    GUICtrlSetData($hProgress, 0)
    _ButtonState($GUI_ENABLE)
    EndFunc ;==>_DevCon

    [/autoit] [autoit][/autoit] [autoit]

    Func _UPDATE()
    _ButtonState($GUI_DISABLE)
    $aUSBDRIVES = _GetUSBDrives()
    For $i = 0 To _GUICtrlListView_GetItemCount($hListView)
    _GUICtrlListView_SetItemText($hListView, $i, "DISABLED", 2)
    Next
    _Add2LV($aUSBDRIVES)
    _ButtonState($GUI_ENABLE)
    EndFunc ;==>_UPDATE

    [/autoit] [autoit][/autoit] [autoit]

    Func _DISABLE()
    _DevCon("disable")
    EndFunc ;==>_DISABLE

    [/autoit] [autoit][/autoit] [autoit]

    Func _ENABLE()
    _DevCon("enable")
    EndFunc ;==>_ENABLE

    [/autoit] [autoit][/autoit] [autoit]

    Func _REMOVE()
    _DevCon("remove")
    EndFunc ;==>_REMOVE

    [/autoit] [autoit][/autoit] [autoit]

    Func _RESTART()
    _DevCon("restart")
    EndFunc ;==>_RESTART

    [/autoit] [autoit][/autoit] [autoit]

    Func _SCAN()
    _ButtonState($GUI_DISABLE)
    $iPGCnt = 0
    GUICtrlSetStyle($hProgress, $PBS_MARQUEE)
    AdlibEnable("_Progress", 10)
    RunWait($Devcon & " rescan", "", @SW_HIDE)
    AdlibDisable()
    GUICtrlSetStyle($hProgress, 0)
    GUICtrlSetData($hProgress, 0)
    _UPDATE()
    EndFunc ;==>_SCAN

    [/autoit] [autoit][/autoit] [autoit]

    Func _Add2LV($aUSB)
    If Not IsArray($aUSB) Then Return
    Local $iIndex
    For $i = 1 To $aUSB[0][0]
    $iIndex = _GUICtrlListView_FindInText($hListView, $aUSB[$i][2])
    If $iIndex >= 0 Then
    _GUICtrlListView_SetItemText($hListView, $iIndex, "ENABLED", 2)
    ContinueLoop
    EndIf
    $iIndex = _GUICtrlListView_AddItem($hListView, $aUSB[$i][0])
    _GUICtrlListView_AddSubItem($hListView, $iIndex, $aUSB[$i][1], 1)
    _GUICtrlListView_AddSubItem($hListView, $iIndex, "ENABLED", 2)
    _GUICtrlListView_AddSubItem($hListView, $iIndex, $aUSB[$i][2], 3)
    Next
    $B_DESCENDING = True
    _GUICtrlListView_SimpleSort($hListView, $B_DESCENDING, 1)
    EndFunc ;==>_Add2LV

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetUSBDrives($ComputerName = ".")
    Local $wmiServices, $wmiUsbDevice, $wmiDiskDrive, $wmiDiskPartitions, $wmiLogicalDisks
    Local $USBDevice, $DiskDrive, $DiskPartition, $LogicalDisk, $aRet[1][3], $iCnt = 0
    Local $iSteps = 0, $iStep = 0
    $wmiServices = ObjGet("winmgmts:{impersonationLevel=Impersonate}!//" & $ComputerName)
    $wmiUsbDevice = $wmiServices.ExecQuery("SELECT * FROM Win32_USBControllerDevice")
    For $USBDevice In $wmiUsbDevice
    $iSteps += 1
    Next
    For $USBDevice In $wmiUsbDevice
    $iStep += 1
    GUICtrlSetData($hProgress, Round($iStep * 100 / $iSteps))
    $wmiDiskDrive = $wmiServices.ExecQuery("ASSOCIATORS OF {Win32_PnPEntity.DeviceID=" & StringTrimLeft($USBDevice.Dependent, StringInStr($USBDevice.Dependent, "=")) & "} WHERE ResultClass = Win32_DiskDrive")
    For $DiskDrive In $wmiDiskDrive
    $wmiDiskPartitions = $wmiServices.ExecQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & $DiskDrive.DeviceID & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition")
    For $DiskPartition In $wmiDiskPartitions
    $wmiLogicalDisks = $wmiServices.ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & $DiskPartition.DeviceID & "'} WHERE AssocClass = Win32_LogicalDiskToPartition")
    For $LogicalDisk In $wmiLogicalDisks
    $iCnt += 1
    ReDim $aRet[$iCnt + 1][3]
    $aRet[$iCnt][0] = $LogicalDisk.DeviceID
    $aRet[$iCnt][1] = $DiskDrive.Caption
    $aRet[$iCnt][2] = '"@' & StringTrimLeft(StringReplace(StringTrimLeft($USBDevice.Dependent, StringInStr($USBDevice.Dependent, "=")), "\\", "\"), 1)
    Next
    Next
    Next
    Next
    $aRet[0][0] = $iCnt
    GUICtrlSetData($hProgress, 0)
    Return $aRet
    EndFunc ;==>_GetUSBDrives

    [/autoit] [autoit][/autoit] [autoit]

    Func _EXIT()
    Exit
    EndFunc ;==>_EXIT

    [/autoit]

    ps.: Und sorry, daß ich dir auch noch das Design geklaut hab :D

    lgE

  • eukalyptus:

    Ich habe mir Deine WMI-Version jetzt nicht extra angesehen.

    Nur einen Tip den ich beim Arbeiten mit WMI feststellen musste:
    Nicht alle WMI-Abfragen dürfen auch "Normalsterbliche"-User durchführen.
    Einiges ist den Admins vorbehalten. Also immer schön als Nicht-Admin testen.

    Aber wie gesagt, muss bei Deinem Script nicht zutreffen.

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    • Offizieller Beitrag

    Ist mir vorher gar nicht aufgefallen - aber wenn du per Gerätemanager den Stick abmeldest, kann devcon nichts mehr erkennen. Das ist auch sichtbar, wenn du mit devcon abmeldest. Dann verbleibt trotzdem das Symbol für die Hardwareabmeldung im Tray, nur ohne Lw-Buchstaben. Die Abmeldung durch devcon ist also keine echte Hardwareentfernung.
    Ich habe keine 2 identischen Sticks, sie nutzen aber dieselbe Bezeichnung, haben aber unterschiedliche ID's.

  • Hallo,

    ich bekomme leider auch eine Fehlermeldung (OS=Windows XP SP3, MUL):

    Aufruf aus SciTE (V1.76):

    [autoit]

    >Running:(3.2.12.1):C:\Program Files\AutoIt3\autoit3.exe "D:\Scripts\ManageUSB.au3"
    D:\Scripts\ManageUSB.au3 (138) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    $tmp = StringSplit($tmp[2], @LF)
    $tmp = StringSplit(^ ERROR
    ->12:01:06 AutoIT3.exe ended.rc:1
    >Exit code: 1 Time: 2.065

    [/autoit]

    Nach dem compilieren:
    Es erscheint das Fenster "Manage USB-Drive" allerdings auch eine Fehlermeldung:
    "AutoIt Error"
    Line -1:
    Error: Array variable has incorrect number of subscripts or subscript dimension range exceeded.

    mfg
    Axel

    There exist 10 different kind of people on earth.
    Those who understand binary, and those who don't.