Sign in to follow this  
Followers 0
BenT

USB Detection

24 posts in this topic

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?

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

@BenT

I am not an expert but this can get you started.

USB Monitor

Regards,

ptrex

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Too many episodes of Psych?

Never seen it, but my sixth sense tells me that you have.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Isn't that the same thing ptrex posted?

Share this post


Link to post
Share on other sites

Tons a lot for your great help. I'll try it out. :) :)

Share this post


Link to post
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

Share this post


Link to post
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. :)

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

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...

Share this post


Link to post
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
Sign in to follow this  
Followers 0