Sign in to follow this  
Followers 0
SH1NS0U

USB Device detection (Media Device)

7 posts in this topic

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



#2 ·  Posted (edited)

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

#3 ·  Posted (edited)

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

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

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

#6 ·  Posted (edited)

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

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