Jump to content

USB Detection


BenT
 Share

Recommended Posts

Hi All,

I'm new to AutoIT. Just wonder if any idea to detect if USB flash drives are inserted?

I use an infinite loop and poll every 2 sec for removable drives by using function DriveGetDrive. Is there any other way to deal with this?

Link to comment
Share on other sites

I now this code is not perfect but you get the idee of it ? :) it should be something like this:

$var = DriveGetDrive( "all" )
If NOT @error Then
    MsgBox(4096,"", "Found " & $var[0] & " drives")
    $var2=$var[0]
    while 1 
        if $var2 < $var[0] then 
MsgBox(0,"","USB drive has been inserted")
$var2=$var[0]
endif
if $var2 > $var[0] then 
MsgBox(0,"","USB drive has been removed")
$var2=$var[0]
endif


        wend

EndIf
Link to comment
Share on other sites

Ptrex is pretty good with this stuff. I think there is a way to create a synchronous event using WMI. Also when I new device is plugged in, a message is sent to all top level windows with a notification, so you may be able to use GUIRegisterMsg.

Link to comment
Share on other sites

try searching for deveject in this forum. It'll produce a report you can read for most devices, including cables. with wmi you can check another useful tool called scriptomatic in this same forum and you may want to chec the pnpDeviceId and pollit till something changes, but it's not as fast as deveject and not as reliable, in my experience.

regards,

ivan

Link to comment
Share on other sites

  • Moderators

If you aren't the expert then how did I predict that you'd have the solution?

Too many episodes of Psych?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Hi,

Opt('MustDeclareVars', 1)

MsgBox(0, 0, _getNewUSB())

Func _getNewUSB()
    Local $strComputer = ".", $objEvent = 0
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
    Local $colEvents = $objWMIService.ExecNotificationQuery _
            ("Select * From __InstanceOperationEvent Within 5 Where " _
             & "TargetInstance isa 'Win32_LogicalDisk'")
    While 1
        $objEvent = $colEvents.NextEvent
        If $objEvent.TargetInstance.DriveType = 2 Then
            If $objEvent.Path_.Class() = "__InstanceCreationEvent" Then Return $objEvent.TargetInstance.DeviceId
        EndIf
        Sleep(10)
    WEnd
EndFunc   ;==>_getNewUSB

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

Isn't that the same thing ptrex posted?

Hi,

not at all, it is stripped a little and put into a func for easy use. :)

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

Thanks guys. I tried it out and it works great.

Could I ask one more question that how can I obtain the hardware ID string (e.g. Kingmax Flash Disk DD8G and SANDisk Flash Drive UU8G9xx)?

I tried to echo some values such as attributes "Name" and "SystemName" using the code above but no luck. :)

Link to comment
Share on other sites

Thanks guys. I tried it out and it works great.

Could I ask one more question that how can I obtain the hardware ID string (e.g. Kingmax Flash Disk DD8G and SANDisk Flash Drive UU8G9xx)?

I tried to echo some values such as attributes "Name" and "SystemName" using the code above but no luck. :)

Hi,

you mean

MsgBox(0, "", DriveGetLabel("f:"))
???

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

Hi,

Nop. Normally USB embedded a hardware string for ID purpose. It includes things like brand and part number. I'm having difficulty for retrieving the value.

Thanks.

That information isn't stored in Win32_LogicalDisk, its stored in Win32_DiskDrive. I can't find any matching ID for my thumb drive between these two classes though, I don't know how you will match them together as even the PNPDeviceID shows differently.

Link to comment
Share on other sites

The following is one of my first AutoIt ventures, and isn't really mine I think. I believe I copied it from somewhere else on the web, but I fail to remember where that is now. It does kinda what your looking to do, but not really. It takes a Win32_DiskDrive entry, and figures out it's drive letter through several other classes. If nothing else, this could help you figure out how to go the direction you really want to go.

Func GetDriveLetterFromDisk($name)
    $ans = ""
    $name = StringReplace($name,"\","\\")
    $oq_part = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & $name & """} WHERE AssocClass = Win32_DiskDriveToDiskPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($oq_part) Then
        For $obj_part In $oq_part
            $oq_disk = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & $obj_part.DeviceID & """} WHERE AssocClass = Win32_LogicalDiskToPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
            If IsObj($oq_disk) Then
                For $obj_disk in $oq_disk
                    $ans = $ans & $obj_disk.Name
                Next
            EndIf
        Next
    EndIf
    
    Return $ans
EndFunc
Link to comment
Share on other sites

doesn't play nice with machines with floppy drives, causes minor case of bruxism (floppy drive grinding)

floppy LED comes on every 5 seconds (polling rate of WMI script)

can sub Win32_PnPEntity for Win32_LogicalDisk

doesn't block message loop

Edit: changes To Win32_LogicalDisk query and sink function

; asynchronous version
#NoTrayIcon
HotKeySet("{ESC}", "_Quit")
Opt('MustDeclareVars', 1)
Opt("TrayIconHide", 1)

Local $strComputer = "."
Global $output = "", $drv = "", $Timer = 0, $iT
; Global variable timer and output buffers required for multiple drive letters for USB drives and to buffer
; concurrently connected usb drives 

;$strComputer = @ComputerName
;$strComputer = "localhost"
Local $objWMIService, $objContext

Local $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")
Local $SINK = ObjCreate("WbemScripting.SWbemSink")
ObjEvent($SINK, "SINK_")

; add as many queries as needed to sink
; limit to creation events - exclude ongoing drive modification events

; Type 2 removable drives (USB) - get drive letter
; Type 3 fixed drives (external USB hard drive) - multiple drive letters for partitions
$objContext = ObjCreate("WbemScripting.SWbemNamedValueSet")
$objContext.Add("Query", "DriveType")
$objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
If Not @error Then
    $objWMIservice.ExecNotificationQueryAsync($SINK, _ ; 
        "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE " & _
        "TargetInstance ISA 'Win32_LogicalDisk'" & _
        " AND (TargetInstance.DriveType = 2 Or TargetInstance.DriveType = 3)", Default, Default, Default, $objContext)
EndIf
; Interface Type USB - get model info for USB drive
$objContext = ObjCreate("WbemScripting.SWbemNamedValueSet")
$objContext.Add ("Query", "InterfaceType")
$objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
If Not @error Then
    $objWMIservice.ExecNotificationQueryAsync($SINK, _
        "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE " & _
        "TargetInstance ISA 'Win32_DiskDrive'" & _
        " AND TargetInstance.InterfaceType = 'USB'", Default, Default, Default, $objContext)
EndIf

While 1
    Sleep(100)
    _GetUSB()
Wend

Func _Quit()
    Exit
EndFunc

Func _GetUSB() ; only blocks message loop when MsgBox run
    If $Timer <> 0 And (TimerDiff($Timer) >= 1000) Then
        $output = $drv
        $drv = ""
        $Timer = 0
        ToolTip($output, (@DesktopWidth - 250), (@DesktopHeight - 200), "USB Connected")
        $output = ""
        ;MsgBox(0,"USB Drive(s) Connected", $output,10)
    EndIf
EndFunc

Func SINK_OnObjectReady($objObject, $objAsyncContext)
    Switch $objAsyncContext.Item("Query").Value
        Case "InterfaceType"
            $Timer = 0
            $drv &= $objObject.TargetInstance.Model & @CRLF
        Case "DriveType"
            $Timer = 0
            Local $Drive = $objObject.TargetInstance.DeviceId
            $drv &= $objObject.TargetInstance.Description & " " &$Drive & "  " & _
            $objObject.TargetInstance.FileSystem &" VOL: " & _
            $objObject.TargetInstance.VolumeName & @CRLF
            $Timer = TimerInit()
    EndSwitch
EndFunc

Func MyErrFunc()
   Local $HexNumber = Hex($oMyError.number,8)
   ConsoleWrite("Debug:  Intercepted COM Error:  Number = " & $HexNumber & _
        "  Windescription = " & $oMyError.windescription & @LF)
   Return SetError(1)
EndfuncoÝ÷ ÚÚ)
Edited by rover

I see fascists...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...