Jump to content
Sign in to follow this  
SH1NS0U

USB Device detection (Media Device)

Recommended Posts

SH1NS0U

Hi,

I'm new to this forum and also to AutoIT sw. (greate sw btw..)

And I wish to apologies for my bad English. :)

As on my first project I found my self stuck.

#1

I have few USB-media devices (4 models; close to a milj. pcs.. so serialnumber is not the way to go).

I'm creating "autoInstall" program. (for LUsers/newbies... I could do it with C/C++/VB but.. I wish to try AutoIT on this one..)

#2

I came to a part where I wish to detect after the software installation that if the device is connected

( 1. install software, drivers etc.[this part is clear] 2. connect device[stuck here] 3. run the original sw for the device..[have plans :ermm: ])

The "Plan" in a nut:

- Start AutoInstall.exe to run automatic installation of the software.

- After software is installed, request user to connect the USB-device leaving info-window of it; which closes when user have done so(or cancelled). (here stuck)

- After device driver has succesfully installed (or failed to install). Depending on the result, run the device software if able. If fail, return with error... or something ;)

I found this from this forum, but I couldn't make it out.

Dim $DBT_DEVICEARRIVAL = "0x00008000"
Dim $DBT_DEVICECOMPLETEREMOVAL = "0x00008004"
Dim $USB_ATTENTION = "0x00000007"
Dim $WM_DEVICECHANGE = 0x0219
Dim $Drives
Dim $Drive_Type = "ALL"  ; Set to ALL because some USB Drives are detected as Fixed Disks, and we don't want to miss those
Dim $WATCH = False
Dim $MyDrive = "STUFF"

;Get Initial List of Drives to Check Against
UpdateDrives()
;Setup The GUI to watch for the DeviceChange Event
GUICreate("")
GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange")
Func DeviceChange($hWndGUI, $MsgID, $WParam, $LParam)
    Switch $WParam
        Case $USB_ATTENTION
        ; This only happens when USB drives are inserted, so I use it to tell the difference between these and CDROMs
            $WATCH = True
            MsgBox(0, Default, "USB_ATTENTION");   nevermind this part.. it's just for testing..  :P 
        Case $DBT_DEVICECOMPLETEREMOVAL
        ; Whenever a Drive is Removed, Update the Drive List
            UpdateDrives()
        Case $DBT_DEVICEARRIVAL
        ; A drive was inserted
        ; Use $WATCH to tell if this was a CDROM or USB
        ; $WATCH = True, USB
        ; $WATCH = False, CDROM
            If $WATCH = True Then
            ; New USB Drive Was Detected, Time to Find it's Letter
                $New = FindNewDrive(); $New now has the Drive Letter of our New Drive, so USE IT!!!
                $Label = DriveGetLabel($New)
                If $Label == $MyDrive Then
                    MsgBox(4096, "Info", "My Drive has been Inserted, Backup My Files!")
                EndIf
            ; Now Reset Drive List so more insertions can also be detected accurately
                UpdateDrives()
            EndIf
    EndSwitch
EndFunc  ;==>DeviceChange

; This just jumps through the new Drive List, comparing them until it finds the entry that is in the new one that isn't in the old one
Func FindNewDrive()
    $Temp = DriveGetDrive( "REMOVABLE" )
    For $i = 1 to $Temp[0]
        $Old = False
        For $j = 1 to $DRIVES[0]
            If $DRIVES[$j] == $Temp[$i] Then $Old = True
        Next
        If $Old == False Then Return $Temp[$i]
    Next
EndFunc  ;==>FindNewDrive

; Just to keep things neat, and so if Variables Ever Change, this makes updating easier
Func UpdateDrives()
    $Drives = DriveGetDrive( $Drive_Type )
EndFunc  ;==>UpdateDrives

; Main Loop to Keep the Program Open
; No Real Way of ending this program, except for just killing the process
; Which is what I want, an always on backup for my drive every time I insert it
While 1
    $GuiMsg = GUIGetMsg()
; This is needed because the watch event above not only triggers before a USB Drive is inserted/removed,
; but also AFTER insertion too, and if not reset, a subsequent CD insertion will trigger it again.
; So, every second, we reset $WATCH, to keep things clean
    Sleep (1000)
    $WATCH = False
WEnd

Any help would be appreciated.

Cheers

Share this post


Link to post
Share on other sites
SH1NS0U

Hi,

It seems that no one have answered to my question. So I raise the bets. Here is a littlebit of C# (bad one; quite quick made...)

Can some one convert / translate :) this to AutoIT ?

(also if someone knows some of C# and can make better, do not hesitate to do so; do also show me the results...)

static void Main()
        {
            string[] usbDevices = GetUSBDevices();
            string found = usbDevices.ToString();
            // If found the device, tell it and exit.
            if (found.ToLower() != "")
            {
                Console.WriteLine("Found device!");
                Console.WriteLine("Exiting...");
                Environment.Exit(0);
            }
            else {
            // err, well... in this part we never get to..
                Console.WriteLine("Searching for device...");
            }
            //Console.ReadKey();
        }

        static string[] GetUSBDevices()
        {
            List<string> list = new List<string>();
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice");
            foreach (ManagementObject mo in searcher.Get())
            {
                string dependent = mo["Dependent"].ToString();
                string deviceId = dependent.Split('=')[1];
                deviceId = deviceId.Replace('\"', '\'');
                //Console.WriteLine("DeviceID: " + deviceId);
                ManagementObjectSearcher searcher2 = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity Where DeviceID LIKE '%PID_861F%'");
                do
                {
                    foreach (ManagementObject mo2 in searcher2.Get())
                    {
                        //Here we get the device friendly name and print it out...
                        string description = mo2["Description"].ToString();
                        //list.Add(description);
                        //Console.WriteLine(description);
                        //Console.WriteLine(description);
                    }
                } while (searcher2.Get().Count == 0);
            }
            //Here we get the list from array and return the result.
            string[] usbDevices = list.ToArray();
            
            return usbDevices;
        }
Edited by SH1NS0U

Share this post


Link to post
Share on other sites
mesale0077

SH1NS0U thank you for this code

but this code changed but dont work ,usb log

Dim $DBT_DEVICEARRIVAL = "0x00008000"

Dim $DBT_DEVICECOMPLETEREMOVAL = "0x00008004"

Dim $USB_ATTENTION = "0x00000007"

Dim $WM_DEVICECHANGE = 0x0219

Dim $Drives

Dim $Drive_Type = "ALL" ; Set to ALL because some USB Drives are detected as Fixed Disks, and we don't want to miss those

Dim $WATCH = False

Dim $MyDrive = "STUFF"

;Get Initial List of Drives to Check Against

UpdateDrives()

;Setup The GUI to watch for the DeviceChange Event

GUICreate("")

GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange")

Func DeviceChange($hWndGUI, $MsgID, $WParam, $LParam)

Switch $WParam

Case $USB_ATTENTION

; This only happens when USB drives are inserted, so I use it to tell the difference between these and CDROMs

$WATCH = True

; MsgBox(0, Default, "USB_ATTENTION");

write()

; nevermind this part.. it's just for testing.. ;)

Case $DBT_DEVICECOMPLETEREMOVAL

; Whenever a Drive is Removed, Update the Drive List

UpdateDrives()

Case $DBT_DEVICEARRIVAL

; A drive was inserted

; Use $WATCH to tell if this was a CDROM or USB

; $WATCH = True, USB

; $WATCH = False, CDROM

If $WATCH = True Then

; New USB Drive Was Detected, Time to Find it's Letter

$New = FindNewDrive(); $New now has the Drive Letter of our New Drive, so USE IT!!!

$Label = DriveGetLabel($New)

If $Label == $MyDrive Then

MsgBox(4096, "Info", "My Drive has been Inserted, Backup My Files!")

EndIf

; Now Reset Drive List so more insertions can also be detected accurately

UpdateDrives()

EndIf

EndSwitch

EndFunc ;==>DeviceChange

; This just jumps through the new Drive List, comparing them until it finds the entry that is in the new one that isn't in the old one

Func FindNewDrive()

$Temp = DriveGetDrive( "REMOVABLE" )

For $i = 1 to $Temp[0]

$Old = False

For $j = 1 to $DRIVES[0]

If $DRIVES[$j] == $Temp[$i] Then $Old = True

Next

If $Old == False Then Return $Temp[$i]

Next

EndFunc ;==>FindNewDrive

; Just to keep things neat, and so if Variables Ever Change, this makes updating easier

Func UpdateDrives()

$Drives = DriveGetDrive( $Drive_Type )

; Check if file opened for writing OK

EndFunc ;==>UpdateDrives

func write()

$log = @ScriptDir &"/flash.txt"

$var = DriveGetDrive( "all" )

FileOpen($log, 1)

For $i = 1 to $var[0]

If NOT @error and $var[$i] > "f" Then

;FileWrite($log,$var[$i] &@MDAY & "." & @MON & "." & @YEAR& " " & @HOUR & ":" & @MIN & ":" &" name: "&DriveGetLabel($var[$i] )&" Serial: " & DriveGetSerial($var[$i] ) &" total: "& Round ( DriveSpaceTotal($var[$i] ) )& @CRLF )

FileWrite($log,$var[$i] &@MDAY & "." & @MON & "." & @YEAR& " " & @HOUR & ":" & @MIN & ":" & @SEC & " name: "&DriveGetLabel($var[$i] )&" Serial: " & DriveGetSerial($var[$i] ) &" total: "& Round ( DriveSpaceTotal($var[$i] ) )& @CRLF ) <-------this problem look it flash.txt more usb name write ,why

EndIf

Next

FileClose($log)

Return

EndFunc

; Main Loop to Keep the Program Open

; No Real Way of ending this program, except for just killing the process

; Which is what I want, an always on backup for my drive every time I insert it

While 1

$GuiMsg = GUIGetMsg()

; This is needed because the watch event above not only triggers before a USB Drive is inserted/removed,

; but also AFTER insertion too, and if not reset, a subsequent CD insertion will trigger it again.

; So, every second, we reset $WATCH, to keep things clean

Sleep (1000)

$WATCH = False

WEnd

Edited by mesale0077

Share this post


Link to post
Share on other sites
AwAke

To detect the insertion of a USB drive use this code. Its similar to the C# example you posted.

$strComputer = "."
$objWMIServices = ObjGet("winmgmts:" & "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
$sink = ObjCreate("WbemScripting.SWbemSink")
ObjEvent($sink, "SINK_")
$objWMIServices.ExecNotificationQueryAsync($sink, "SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " & "TargetInstance ISA 'Win32_LogicalDisk'")
;- End of setting up the WMI event ----------------

;- The event that is called upon detecting a USB storage device.
Func sink_OnObjectReady($objObject, $objAsyncContext)
    Local $choice
    If $objObject.TargetInstance.DriveType = 2 Then ;- TargetIstance.DriveType = 2 means a Removable drive.
        Select
            Case $objObject.Path_.Class () = "__InstanceCreationEvent" ;- Storage Device is plugged in.
                ConsoleWrite("Drive " & $objObject.TargetInstance.DeviceId & "has been removed." & @CR)
            Case $objObject.Path_.Class () = "__InstanceDeletionEvent" ;- Storage device has been removed.
                ConsoleWrite("Drive " & $objObject.TargetInstance.DeviceId & "has been removed." & @CR)
        EndSelect
    EndIf
EndFunc

Credits goes to wolf9228 here -> http://www.autoitscript.com/forum/index.php?showtopic=103421&st=0&p=732733&#entry732733

Share this post


Link to post
Share on other sites
mesale0077

thank you but

line 5 error

$objWMIServices.ExecNotificationQueryAsync($sink, "SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " & "TargetInstance ISA 'Win32_LogicalDisk'")

$objWMIServices error

Share this post


Link to post
Share on other sites
rajeshontheweb

try this

its from the same link but just abit of modification to make it clear of what u need to use thats all...

#include <WindowsConstants.au3>
$strComputer = "."
$objWMIServices = ObjGet("winmgmts:" & "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")

$sink = ObjCreate("WbemScripting.SWbemSink")
ObjEvent($sink,"SINK_")

 $objWMIServices.ExecNotificationQueryAsync ($sink, "SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " & "TargetInstance ISA 'Win32_LogicalDisk'")

While 1

Wend

Func SINK_OnObjectReady($objObject, $objAsyncContext)
 If $objObject.TargetInstance.DriveType = 2 Then
        Select
            Case $objObject.Path_.Class()="__InstanceCreationEvent"
                Consolewrite("Drive " & $objObject.TargetInstance.DeviceId & " has been added." & @CR)

            Case $objObject.Path_.Class()="__InstanceDeletionEvent"
                ConsoleWrite("Drive " & $objObject.TargetInstance.DeviceId & " has been removed."& @CR)
        EndSelect
    EndIf

EndFunc
Edited by rajeshontheweb

Share this post


Link to post
Share on other sites
rajeshontheweb

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  

×