gingerbloke Posted November 3, 2009 Posted November 3, 2009 I am very new to AutoIt and would appreciate any help I can get with the following: I am writing a small program to backup my system. It works in the following way: It waits for a specific USB Storage Drive to be connected to my computer. If it finds this drive is connected then (using someone else's code from this forum) it finds the drive letter assigned to that device. With this information, I will then be able to backup key information on my system to the USB Drive (plus eventually I hope to 'Image the System as part of the backup but that will probably be a different post) The problem is that the way it finds the drive letter for connected USB device is very slow and I would like it to be faster if possible. (please ignore the message boxes in the below code, they were for checking the progress of the program running) This is the code I am using: DIM $DRIVR DIM $COUNTER dim $COUNTERA DIM $BACKUPDRIVESERIAL DIM $BACKUPDRIVE DIM $BACKUPDRIVEENUM DIM $LEFTBACKUPDRIVEENUM dim $LENBACKUPDRIVEENUM dim $REGISTRYDRIVELOCATION dim $REGISTRYPATH DIM $DRIVEATTACHED DIM $FOUNDDRIVESERIAL DIM $MISCSTRING DIM $DRIVELETTER dim $var dim $i dim $PROGRAMEND ;************************************************************************************************** ;This is the registry entry of the USB drive to search for $BACKUPDRIVE = "USBSTOR\Disk&Ven_Maxtor&Prod_Basics_Desktop&Rev_0128\2HBARK6E____&0" ;************************************************************************************************** ;************************************************************************************************** ;THIS IS THE MAIN PROGRAM CALL Do SLEEP (5000) ;Wait 5 seconds before re-scanning CheckRegistryForDevice(); This works out names and locations of relevent registry entries for the device CheckDriveAttached();Checks if the drive is connected and sub calls other function to find it's drive letter ;If drive attached then notify user we are preparing to backup and find drive letter if $DRIVEATTACHED = 1 then MsgBox(0, $DRIVELETTER, $FOUNDDRIVESERIAL) ;Warn User Backup Starting Shortly ;Check if Drive is attached CheckDriveLetter() endif ; MsgBox(0, $DRIVELETTER, $FOUNDDRIVESERIAL) if $DRIVELETTER <> "" then MsgBox(0, $DRIVELETTER,$FOUNDDRIVESERIAL);Run The Backup Program. until $PROGRAMEND = 5 exit ;************************************************************************************************** ;FUNCTIONS ARE HERE ;************************************************************************************************** ;************************************************************************************************** Func CheckRegistryForDevice() ;This works out the device serial number that should be held in the registry ;Uses device name ie $BACKUPDRIVE = "USBSTOR\Disk&Ven_Maxtor&Prod_Basics_Desktop&Rev_0128\2HBARK6E____&0" ;And looks for this device where Disk Drives (fixed and Removable are located $PROGRAMEND = 0 $REGISTRYPATH = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"; Location where Disk Drive info found ;SET THE USB DEVICE SERIAL NO & REGISTRY TEXTS $BACKUPDRIVEENUM = StringReplace($BACKUPDRIVE, "\", "#") $BACKUPDRIVEENUM = "##?#" & $BACKUPDRIVEENUM $LENBACKUPDRIVEENUM = StringLen($BACKUPDRIVEENUM) ;************************************************************************************************** ;Work Out the Serial Number for this device $LENBACKUPDRIVEENUM = StringLen($BACKUPDRIVE) for $COUNTER = 1 to $LENBACKUPDRIVEENUM $MISCSTRING = StringMid($BACKUPDRIVE, $COUNTER, 1) if $MISCSTRING = "\" then ;Strip Off the left Hand Side of the string $COUNTERA = $LENBACKUPDRIVEENUM - $COUNTER $BACKUPDRIVESERIAL = StringRight($BACKUPDRIVE, $COUNTERA) ; MsgBox(0, $BACKUPDRIVESERIAL, $COUNTERA) endif next ;Now strip off the unnecessary right side of the String $LENBACKUPDRIVEENUM = StringLen($BACKUPDRIVESERIAL) for $COUNTER = 1 to $LENBACKUPDRIVEENUM $MISCSTRING = StringMid($BACKUPDRIVESERIAL, $COUNTER, 1) ;MsgBox(0, $MISCSTRING, $COUNTER) if $MISCSTRING = "_" then ;Strip Off the right Hand Side of the string $COUNTERA = $COUNTER - 1 $BACKUPDRIVESERIAL = StringLeft($BACKUPDRIVESERIAL, $COUNTERA) $BACKUPDRIVESERIAL =StringStripWS($BACKUPDRIVESERIAL, 2) ; MsgBox(0, $BACKUPDRIVESERIAL, $COUNTERA) ;Got $BACKUPDRIVESERIAL exitloop endif next EndFunc Func CheckDriveAttached() ;-------------------------------------------------------------------------------------------------- ;Get All Installed Drives on The System and check for our device and if it is connected $i = 0 $DRIVEATTACHED = 0 while $REGISTRYDRIVELOCATION <> "end" $i= $i + 1 $REGISTRYDRIVELOCATION = "" $REGISTRYDRIVELOCATION = RegEnumKey($REGISTRYPATH, $i) If @error <> 0 then ExitLoop ;Check for our device entry here $LEFTBACKUPDRIVEENUM = StringLeft($REGISTRYDRIVELOCATION, $LENBACKUPDRIVEENUM) ;Now check to see if we can find the registry location of our device if $LEFTBACKUPDRIVEENUM = $BACKUPDRIVEENUM then ;Now check if the device is connected at the moment $REGISTRYDRIVELOCATION = $REGISTRYPATH & "\" & $REGISTRYDRIVELOCATION & "\Control" $DRIVEATTACHED = RegRead($REGISTRYDRIVELOCATION, "ReferenceCount") ; if $DRIVEATTACHED = 1 then CheckDriveLetter();MsgBox(4096, "Drive attached", $REGISTRYDRIVELOCATION) ;Device connected so prepare to begin backup endif wend ;-------------------------------------------------------------------------------------------------- endfunc Func CheckDriveLetter() ;Now Get the drive letter for our device by checking each connected drive letter in turn $varall = DriveGetDrive("all") for $i = 1 to $varall[0] $FOUNDDRIVESERIAL = "" $DRIVR = $varall[$i] getSerialNumberFromDriveLetter(); For the given Drive letter find the devices serial number to see if it is our device MsgBox(0, $FOUNDDRIVESERIAL, $DRIVR) if $FOUNDDRIVESERIAL = $BACKUPDRIVESERIAL then $DRIVELETTER = $DRIVR MsgBox(0, $DRIVELETTER, $FOUNDDRIVESERIAL) exitloop endif Next endfunc Func getSerialNumberFromDriveLetter() ;************************************************************************** ;************* THIS PART IS THE BOTTLENECK IN THE PROGRAM ***************** ;************************************************************************** ;Search each provided drive letter for it's serial number $DRIVR Dim $I = 0 , $X = 0 ,$ComputerName = '.' $wmiServices = ObjGet ("winmgmts:{impersonationLevel=Impersonate}!//" & $ComputerName) $wmiDiskDrives = $wmiServices.InstancesOf("Win32_DiskDrive") For $wmiDiskDrive In $wmiDiskDrives $I = $I + 1 $query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & $wmiDiskDrive.DeviceID & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition" $wmiDiskPartitions = $wmiServices.ExecQuery($query) For $wmiDiskPartition In $wmiDiskPartitions $wmiLogicalDisks = $wmiServices.ExecQuery ("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & $wmiDiskPartition.DeviceID & "'} WHERE AssocClass = Win32_LogicalDiskToPartition") For $wmiLogicalDisk In $wmiLogicalDisks IF StringUpper($wmiLogicalDisk.DeviceID) = StringUpper($DRIVR) Then $X = $I Next Next Next $I = 0 $PhysicalMedia = $wmiServices.InstancesOf("Win32_PhysicalMedia") For $Item In $PhysicalMedia $I = $I + 1 IF $I = $X Then $FOUNDDRIVESERIAL = $Item.SerialNumber $FOUNDDRIVESERIAL =StringStripWS($FOUNDDRIVESERIAL, 2) ;$DRIVELETTER = $DRIVR endif Next EndFunc Thanks for your time ...
Moderators Melba23 Posted November 3, 2009 Moderators Posted November 3, 2009 gingerbloke,Welcome to the AutoIt forums. A good start - some code to work on and a clear question. I wish some other newcomers would do the same.Here is the code I use to get USB serials (credit to spudw2k):expandcollapse popup; credit spudw2k $aDrives = DriveGetDrive("Removable") For $i = 1 To $aDrives[0] $id = _GetPNPDeviceID($aDrives[$i]) MsgBox(0, $aDrives[$i], $id) Next Func _GetPNPDeviceID($drive, $fullid = 0) $objWMIService = ObjGet("winmgmts:{impersonationLevel=Impersonate}!\\.\root\cimv2") If Not IsObj($objWMIService) Then Return -1 ;Failed to Connect to WMI on Local Machine $colDevice = $objWMIService.ExecQuery("SELECT * from Win32_LogicalDiskToPartition") $var = "" For $objItem In $colDevice If StringInStr($objItem.Dependent, $drive) Then $var = StringTrimLeft($objItem.Antecedent, StringInStr($objItem.Antecedent, "=")) EndIf Next If Not $var Then Return -2 ;Failed to Find Drive Letter $colDevice = $objWMIService.ExecQuery("SELECT * from Win32_DiskDriveToDiskPartition") $diskpartition = $var $var = "" For $objItem In $colDevice If StringInStr($objItem.Dependent, $diskpartition) Then $var = StringTrimLeft($objItem.Antecedent, StringInStr($objItem.Antecedent, "=")) EndIf Next If Not $var Then Return -3 ;Failed to Find Physical Drive # $colDevice = $objWMIService.ExecQuery("SELECT * from Win32_DiskDrive") $physicaldrive = StringReplace(StringReplace($var, "\\", "\"), '"', "") $var = "" For $objItem In $colDevice If $objItem.DeviceID = $physicaldrive Then $var = $objItem.PNPDeviceID EndIf Next If Not $var Then Return -4 ;Failed to Find PNPDeviceID If Not $fullid Then $var = StringTrimLeft($var, StringInStr($var, "\", 0, -1)) ;Return Ugly Full PNPDeviceID Return $var EndFunc ;==>_GetPNPDeviceIDIt is pretty fast on my machine - I hope it is fast enough for you! M23P.S. Please use Code tags when you post. Put [autoit ] before and [/autoit ] after your code (but omit the trailing space - it is only there so the tags display here). Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
gingerbloke Posted November 4, 2009 Author Posted November 4, 2009 Thanks for your speedy reply M23, much appreciated. I have run your script but for some reason it returns -2 for all drives found. I will have a play around and see if I can get it to work for me. It may be because I am working on VISTA so I will also try it by booting into my XP and Win7. Also, thanks for the [autoit ] and [/autoit ] pointer, I wondered how to do that with the code. Gingerbloke (but to you Ginge)
Moderators Melba23 Posted November 4, 2009 Moderators Posted November 4, 2009 Ginge, I too am running Vista and I get -2 from "removable" drives such as my card readers, but a valid ID (and an additional drive in the array) as soon as I put a thumb drive into a USB slot. Try looking at the array to see what drives the script finds: #include <Array.au3> $aDrives = DriveGetDrive("Removable") _ArrayDisplay($aDrives) M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
gingerbloke Posted November 5, 2009 Author Posted November 5, 2009 M23 Sorted! on my system the attached USB Hard Drive is detected as a "Local Disk" Type so the Drive letter does not appear in the list. Ive changed it to fixed and it finds the device and serial number really quick. This has also helped me find out which Partitions are part of the same physical device (another project I am working on) because the different drive letter's gives the same serial number for that device. Thanks for your help M23, I owe you one Ginge
AwAke Posted November 5, 2009 Posted November 5, 2009 Funnily enough I am working on a artifact project in College and have been programming a USB Storage program that supports; [*] Different USB Drives (Identifies different drives using DriveGetSerial and backs up accordingly) [*] Full Backup [*] Incremental Backup [*] Backups you're data when working from you're USB Device as you're working (for example, you're working on a file called, 'Test.txt' which is located on your USB drive, - every time you save that document it will backup that file to the directory you specified earlier (in the configuration menu). If you want the source code then I'll PM you it, I'm not going to release it until my project has finished but it may help with the project you're currently under-taking. AwAke.
Neo2102 Posted June 21, 2012 Posted June 21, 2012 Hello, It's possible to have a copy of your source code please ? I need a script for front end user who need to backup profile on a USB drive (Full or Incremental) Thanks
Moderators Melba23 Posted June 21, 2012 Moderators Posted June 21, 2012 Neo2102, As AwAke has not been active here since Mar 2010 I doubt he will answer. In future, please do not necro-post in threads like this when there is little chance of a response. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now