USB Stick dismounten mit ejectmedia.exe

  • Hi Leute,

    so habe nen programm geschrieben das mir einen USB Stick dismountet nachdem ein anderes Programm ihm den Parameter mit dem Laufwerkbuchstaben übergeben hat.

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

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

    If @OSArch = "X64" Then
    _ejectUSB64()
    EndIf

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

    If @OSArch = "X86" Then
    _ejectUSB32()
    EndIf

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

    _SelfDelete()

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

    Func _ejectUSB32($drive = '')
    Local $path = @TempDir & '\EjectMedia.exe'
    If $drive = '' Or $drive = Default Then $drive = StringLeft(@ScriptDir, 2)
    If $cmdLine[0] = 1 And ($cmdLine[1] = '-?' Or $cmdLine[1] = '/?') Then
    MsgBox(64, 'Information', 'Parameter : (Drive) e.g. : E:', 5)
    Exit (0)
    EndIf
    If $cmdLine[0] = 1 Then $drive = $cmdLine[1]
    FileInstall('32\EjectMedia.exe', $path, 1)
    If Not FileExists($drive) Then Return -1
    If Not FileExists($path) Then Return -2
    Run($path & ' ' & $drive & ' -l -f -s -w:1000', @TempDir, @SW_HIDE)
    $Form2 = GUICreate("Please wait...", 501, 120, -1, -1,0)
    $Progress1 = GUICtrlCreateProgress(39, 53, 422, 17, BitOR($PBS_SMOOTH,$PBS_MARQUEE))
    $Label1 = GUICtrlCreateLabel("Dismounting USB Drive...", 39, 19, 124, 17)
    GUICtrlSendMsg($progress1, 0x040A, 1, 35)
    GUISetState()
    Do
    Until ProcessWaitClose("EjectMedia.exe")
    Return 1
    EndFunc ;==>_ejectUSB32

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

    Func _ejectUSB64($drive = '')
    Local $path = @TempDir & '\EjectMedia.exe'
    If $drive = '' Or $drive = Default Then $drive = StringLeft(@ScriptDir, 2)
    If $cmdLine[0] = 1 And ($cmdLine[1] = '-?' Or $cmdLine[1] = '/?') Then
    MsgBox(64, 'Information', 'Parameter : (Drive) e.g. : E:', 5)
    Exit (0)
    EndIf
    If $cmdLine[0] = 1 Then $drive = $cmdLine[1]
    FileInstall('64\EjectMedia.exe', $path, 1)
    If Not FileExists($drive) Then Return -1
    If Not FileExists($path) Then Return -2
    Run($path & ' ' & $drive & ' -l -f -s -w:1000', @TempDir, @SW_HIDE)
    $Form2 = GUICreate("Please wait...", 501, 120, -1, -1,0)
    $Progress1 = GUICtrlCreateProgress(39, 53, 422, 17, BitOR($PBS_SMOOTH,$PBS_MARQUEE))
    $Label1 = GUICtrlCreateLabel("Dismounting USB Drive...", 39, 19, 124, 17)
    GUICtrlSendMsg($progress1, 0x040A, 1, 35)
    GUISetState()
    Do
    Until ProcessWaitClose("EjectMedia.exe")
    Return 1
    EndFunc ;==>_ejectUSB64

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

    Func _SelfDelete($iDelay = 0)
    Local $sCmdFile
    FileDelete(@TempDir & "\scratch.bat")
    $sCmdFile = 'ping -n ' & $iDelay & ' 127.0.0.1 > nul' & @CRLF _
    & ':loop' & @CRLF _
    & 'del "' & @ScriptFullPath & '"' & @CRLF _
    & 'if exist "' & @ScriptFullPath & '" goto loop' & @CRLF _
    & 'del ' & @TempDir & '\scratch.bat'
    FileWrite(@TempDir & "\scratch.bat", $sCmdFile)
    Run(@TempDir & "\scratch.bat", @TempDir, @SW_HIDE)
    EndFunc

    [/autoit]

    Sooooo jetzt hab ich es getestet auf nem 64bit Windows 7, funktioniert.
    Dann auf einem 32bit Win-XP, funktioniert.
    Dann auf einem anderen 32bit Win-XP, funktioniert nicht. Folgende Fehlermeldung:

    [Blockierte Grafik: http://www.bilderload.com/bild/89264/errorHLZC6.jpg]

    Gut, dann habe ich mal gegugt mit @OSArch und @CPUArch. Der zweite Rechner hat nähmlich ein 64bit CPU aber nen 32bit System.
    Jetzt die Frage: Kann es sein das es ein Problem gibt beim ausführen der 32bit exe von EjectMedia ? Immerhin ratert er erstmal 2 sekunden und dann kommt die meldung. Wenn ich jetzt aber die 64bit exe starte dann klappts von anfang an garnicht.

    Grüße cashy ;)

    Einmal editiert, zuletzt von cashmoney (24. Februar 2011 um 08:25)

  • Da der Fehler ja anscheinend nicht aus deinem Script sondern von der ominösen ejectmedia.exe stammt würde ich den Fehler mal dort suchen. Sofern dies ein eigenes Programm ist solltest du den Quellcode dazu posten, andernfalls den Programmierer nach diesem Fehler befragen.

    Nun zu deinem Script:

    [autoit]


    Do
    Until ProcessWaitClose("EjectMedia.exe")

    [/autoit]

    Das ist unsinnig. Innerhalb der Funktion Processwaitclose läuft bereits eine Schleife, warum das ganze nochmals in eine Schleife packen?

  • Also das Programm hab ich hier im Forum gefunden als ich nach Automatischen Trennen von USB Sticks gesucht habe. Aber gut kann man nunmal nichts machen wenns nicht am AutoIT script liegt.

    JA wenn ich das DO UNTIL nicht dirn habe, dann startet er die EjectMedia.exe und beendet das Script sofort. Habe das schon ausgetestet.

    EDIT: achja wo ist den die erste schleife? ich seh nur meine DO UNTIL

  • Das do until war ja gemeint. Die eigentliche Schleife läuft in der wait Funktion, solange dort kein Timeout als Parameter definiert ist müsste er warten bis der Prozess nicht mehr existiert, also nix weiter als eine Schleife die processexists abfragt.

    Du könntest das aber auch komplett ohne diese Funktion machen und zwar indem du runwait anstelle von run benutzt und deine GUI bereits am Anfang erstellst, noch bevor zwischen 32 und 64bit unterschieden wird.

    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

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

    ; GUI Erstellung:

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

    $Form2 = GUICreate("Please wait...", 501, 120, -1, -1,0)
    $Progress1 = GUICtrlCreateProgress(39, 53, 422, 17, BitOR($PBS_SMOOTH,$PBS_MARQUEE))
    $Label1 = GUICtrlCreateLabel("Dismounting USB Drive...", 39, 19, 124, 17)
    GUICtrlSendMsg($progress1, 0x040A, 1, 35)
    GUISetState()

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

    If @OSArch = "X64" Then
    _ejectUSB64()
    EndIf

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

    If @OSArch = "X86" Then
    _ejectUSB32()
    EndIf

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

    _SelfDelete()

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

    Func _ejectUSB32($drive = '')
    Local $path = @TempDir & '\EjectMedia.exe'
    If $drive = '' Or $drive = Default Then $drive = StringLeft(@ScriptDir, 2)
    If $cmdLine[0] = 1 And ($cmdLine[1] = '-?' Or $cmdLine[1] = '/?') Then
    MsgBox(64, 'Information', 'Parameter : (Drive) e.g. : E:', 5)
    Exit (0)
    EndIf
    If $cmdLine[0] = 1 Then $drive = $cmdLine[1]
    FileInstall('32\EjectMedia.exe', $path, 1)
    If Not FileExists($drive) Then Return -1
    If Not FileExists($path) Then Return -2
    Runwait($path & ' ' & $drive & ' -l -f -s -w:1000', @TempDir, @SW_HIDE)
    Return 1
    EndFunc ;==>_ejectUSB32

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

    Func _ejectUSB64($drive = '')
    Local $path = @TempDir & '\EjectMedia.exe'
    If $drive = '' Or $drive = Default Then $drive = StringLeft(@ScriptDir, 2)
    If $cmdLine[0] = 1 And ($cmdLine[1] = '-?' Or $cmdLine[1] = '/?') Then
    MsgBox(64, 'Information', 'Parameter : (Drive) e.g. : E:', 5)
    Exit (0)
    EndIf
    If $cmdLine[0] = 1 Then $drive = $cmdLine[1]
    FileInstall('64\EjectMedia.exe', $path, 1)
    If Not FileExists($drive) Then Return -1
    If Not FileExists($path) Then Return -2
    Runwait($path & ' ' & $drive & ' -l -f -s -w:1000', @TempDir, @SW_HIDE)
    Return 1
    EndFunc ;==>_ejectUSB64

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

    Func _SelfDelete($iDelay = 0)
    Local $sCmdFile
    FileDelete(@TempDir & "\scratch.bat")
    $sCmdFile = 'ping -n ' & $iDelay & ' 127.0.0.1 > nul' & @CRLF _
    & ':loop' & @CRLF _
    & 'del "' & @ScriptFullPath & '"' & @CRLF _
    & 'if exist "' & @ScriptFullPath & '" goto loop' & @CRLF _
    & 'del ' & @TempDir & '\scratch.bat'
    FileWrite(@TempDir & "\scratch.bat", $sCmdFile)
    Run(@TempDir & "\scratch.bat", @TempDir, @SW_HIDE)
    EndFunc

    [/autoit]
  • Da beide Funktion bis auf das Fileinstall identisch sind könntest du auch noch folgende Optimierung umsetzen:

    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

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

    ; GUI Erstellung:

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

    $Form2 = GUICreate("Please wait...", 501, 120, -1, -1,0)
    $Progress1 = GUICtrlCreateProgress(39, 53, 422, 17, BitOR($PBS_SMOOTH,$PBS_MARQUEE))
    $Label1 = GUICtrlCreateLabel("Dismounting USB Drive...", 39, 19, 124, 17)
    GUICtrlSendMsg($progress1, 0x040A, 1, 35)
    GUISetState()

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

    Global $path = @TempDir & '\EjectMedia.exe' ; global definiert, da nun ausserhalb der Funktion

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

    If @OSArch = "X64" Then
    FileInstall('64\EjectMedia.exe', $path, 1)
    else
    FileInstall('32\EjectMedia.exe', $path, 1)
    EndIf

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

    _ejectUSB()
    _SelfDelete()

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

    Func _ejectUSB($drive = '')
    If $drive = '' Or $drive = Default Then $drive = StringLeft(@ScriptDir, 2)
    If $cmdLine[0] = 1 And ($cmdLine[1] = '-?' Or $cmdLine[1] = '/?') Then
    MsgBox(64, 'Information', 'Parameter : (Drive) e.g. : E:', 5)
    Exit (0)
    EndIf
    If $cmdLine[0] = 1 Then $drive = $cmdLine[1]
    If Not FileExists($drive) Then Return -1
    If Not FileExists($path) Then Return -2
    Runwait($path & ' ' & $drive & ' -l -f -s -w:1000', @TempDir, @SW_HIDE)
    Return 1
    EndFunc ;==>_ejectUSB

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

    Func _SelfDelete($iDelay = 0)
    Local $sCmdFile
    FileDelete(@TempDir & "\scratch.bat")
    $sCmdFile = 'ping -n ' & $iDelay & ' 127.0.0.1 > nul' & @CRLF _
    & ':loop' & @CRLF _
    & 'del "' & @ScriptFullPath & '"' & @CRLF _
    & 'if exist "' & @ScriptFullPath & '" goto loop' & @CRLF _
    & 'del ' & @TempDir & '\scratch.bat'
    FileWrite(@TempDir & "\scratch.bat", $sCmdFile)
    Run(@TempDir & "\scratch.bat", @TempDir, @SW_HIDE)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • geänder, danke!

    jetzt nochn problem, das TrayIcon wird immer angezeigt obwohl ich #NoTrayIcon und Opt("TrayIconHide", 1) probiert habe, auch beides zusammen!

  • habs unter Win7 64bit, und Win XP 32bit getestet.

    kann es sein das es überschrieben wird wenn im weiteren script andere befehle kommen wie:
    TraySetClick (0)
    TraySetState ()
    TraySetToolTip("test")

  • Zitat aus der Hilfe zu traysestate()

    Zitat

    Shows the tray icon (default)
    Remarks

    This function overrides the "TrayIconHide"-option and "#NoTrayIcon"-setting.
    The normal and pause tray icon are NOT reset by this function!

    Noch fragen? ^^

  • schön, dann ist dein Problem ja gelöst, schön wäre es allerdings auch wenn du den Thread auf gelöst setzt. Einfach 1. Beitrag bearbeiten, Präfix (nähe Überschrift) ändern und speichern (absenden)

    mfg autoBert