SkinnyWhiteGuy Posted March 10, 2007 Share Posted March 10, 2007 Hello all, I've recently gotten into AutoIt, and so far, I love it. All those old hacks and tricks I used to do with BAT files are now trivial, and I'm on to bigger and better things. That being said, I have a slight problem.My latest project involves USB Drives. I am trying to write a script that, while running on the computer, can detect when a USB drive is inserted, and automatically backup my files off of it (given the Label matches). I've gotten a good bit of the code figured out, but I'm stuck. I was wondering if anyone could help me.Here's the code I have so far:$DBT_DEVICEARRIVAL = "0x00008000" $WM_DEVICECHANGE = 0x0219 GUICreate("") GUIRegisterMsg($WM_DEVICECHANGE , "MyFunc") Func MyFunc($hWndGUI, $MsgID, $WParam, $LParam) If $WParam == $DBT_DEVICEARRIVAL Then ; Find newly inserted Drive here, test for correct label, and then backup files from it EndIf EndFunc While 1 $GuiMsg = GUIGetMsg() WEndIt can successfully detect whenever a new Device is inserted into the computer just fine, there's just 2 problems with it so far:1. It can't tell the difference between a newly inserted CD and a newly inserted USB drive, which is not good, as I would like for it to only trigger on USBs2. Even though it can detect that something was inserted, it can't find the drive in question (by Letter, I mean). I could make a function that, whenever something was inserted, compare it to a list of drives before the insertion, and the difference has to be my new drive, but that's ugly, and also means I'd have to investigate as to detecting when drives were removed to keep my list clean.From all of my readings and Googling, all I can come up with is that the $LParam has something to do with what kind of drive is being inserted, and where it might be located (as per this article). But, I can't seem to detect the differences with what I have so far.If anyone can help me, I would greatly appreciate it. Thanks for any help you provide me. Link to comment Share on other sites More sharing options...
smashly Posted March 10, 2007 Share Posted March 10, 2007 (edited) Sorry I don't have answer to you question , but I'd just like to say thank you for your function This was just what I was looking for. I use your function to detect when my psp is plugged in and sharing it's flash memory so it auto updates my modified files to the flash. For me to check that your function has the correct drive I'm using a sloppy approach , but it works all the same. I use DriveGetDrive() to list the drives available DriveGetType() to get the type of drive ("REMOVABLE" is what I'm after) $DBT_DEVICEARRIVAL = "0x00008000" $WM_DEVICECHANGE = 0x0219 GUICreate("") GUIRegisterMsg($WM_DEVICECHANGE , "MyFunc") Func MyFunc($hWndGUI, $MsgID, $WParam, $LParam) If $WParam == $DBT_DEVICEARRIVAL Then $dg = DriveGetDrive( "REMOVABLE" ) For $i = 1 to $dg[0] $dt = DriveGetType( $dg[$i] ) If $dt = "REMOVABLE" And $dg[$i] <> "a:" And $dg[$i] <> "b:" Then ;;look for my marker file at $dg[$i] , if found do check... MsgBox(4096,"Drive " & $i, $dg[$i] & " = " & $dt) EndIf Next EndIf EndFunc While 1 $GuiMsg = GUIGetMsg() WEnd If removable drive is found then I look for a unique marker file on the removable drive that I have an MD5 for and compare. If the removable drive has this correct marker file then I know it's the drive I'm looking for. If there is no marker file on the removable drive then check the next removable drive and ... so on Once I have the correct drive I then do a file compare from my update archive on the pc with the plugged in psp flash memory... If there are differences in the files on the pc and psp (md5 check all files compare), time stamp is newer and psp flash has enough space then they are transfered to the psp flash memory. Must admit I'm still trying to quash some minor bugs in my script, method is crude but works for my needs. Thank You & Cheers. Edited March 10, 2007 by smashly Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted March 10, 2007 Author Share Posted March 10, 2007 Well, I did some more work on it, and did manage to get it to tell the difference between a CD insertion and USB, though it's a crude hack at best. It ends up using the Drive Removal Event, too, so I may end up just hacking it all together without using the LParam, but I have a very strong feeling there's an easier way to do all this than I'm seeing. I can't post it this weekend. It's on my computer at work, so I'll try to post it Monday. @Smashly: Glad I could be of some assistance, and I think I can help you even more. The DriveGetDrive your using supports "REMOVABLE" as an argument, so that next step you were doing to test for removable can be skipped by just using that arguement. Link to comment Share on other sites More sharing options...
smashly Posted March 10, 2007 Share Posted March 10, 2007 (edited) Yep the "REMOVABLE" argument is what I use , but most times I have multiple removable drives on my PC.. Even a: or b: drives are classed as removable. this is why I exclude a: and b: and check for more then 1 removable drive against a marker file. edited my post above with what I mean. Cheers Edit I see what you mean , use DriveGetDrive for "removable" drives only. But the funny thing is if I have a removable drive already plugged in and I put a cdrom in the drive then it invokes the script again, not really a problem as the script still sees the correct removable drive. just a quirk you could say... lol Edited March 10, 2007 by smashly Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted March 10, 2007 Author Share Posted March 10, 2007 I know, any media insertion will trigger the script I gave here (even floppy, if I'm not mistaken. Haven't tested).I've done a good bit more digging, and come up with something that's both promising and disconcerting:Latest FindThis version of basically what I want to do uses VB and the WMI, both of which AutoIt supports wonderfully. I've used WMI ScriptOMatic and seen what things I'd need to do some of what that page shows, but some parts still elude me.While all this is very promising, I can't figure it out, and I have a sinking feeling that the original code I wrote, while interesting, may be thrown out in favor of this new found code, given I, or someone else on here, can figure out what this new script does, and how to get AutoIt to do it too.As a side note, I also realized another use for this script (if you purposefully searched for CD-ROMS): Auto-Ripping of Audio Tracks from each Audio CD you inserted without having to run the program more than once, just have this type of event trigger another script to start the ripping. Hopefully, something like this could make digitizing someone's collection a lot easier. Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted March 11, 2007 Author Share Posted March 11, 2007 Well, I got bored last night/today. Read a whole lot of info, discovered how to read the data from LParam (a struct), then discovered that it too held the same data no matter if I inserted a CD or a USB drive. So, I fought with it, kept trying, couldn't make heads or tails of it that way. I still don't understand near enough about the WMI, especially how to register the event watcher for it, so, I went the ugly route. I give you the USB Backup Script, that, while active, will watch for any inserted drives, and once it detects that the drive is the one you configured, has space to backup specific folders as you wish (I left that part up to anyone else to fill in). Here it is: expandcollapse popupDim $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 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 As good as the above code works, I'd still love to see the WMI version. I'll write it myself, I just need to know how to register a WMI event watcher to watch for events for me. I know how to do that with VB, but I can't seem to find how to do it in Autoit, and I have this feeling it is possible, I just don't know how to do it. Any help from people here who know more about that than I do would be greatly appreciated. Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted March 12, 2007 Author Share Posted March 12, 2007 Ok, I got a little more time to read around, and found an answer to my own question. I discovered the ExecNotificationQuery, and found that it does the trick just as nice as before, maybe even better. The code at least looks simpler, not as jumbled, just a little more above my head now... I give you the WMI version of the USB Backup Script expandcollapse popup$wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" $MyDrive = "SCSD TOOLS" $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $m_MediaConnectWatcher = $objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_DiskDrive'") While 1 $mbo = $m_MediaConnectWatcher.NextEvent $obj = $mbo.TargetInstance If $obj.InterfaceType == "USB" Then $New = GetDriveLetterFromDisk($obj.Name) $Label = DriveGetLabel($New) If $Label == $MyDrive Then MsgBox(4096, "Info", "My drive has been plugged in, backup my files!") EndIf EndIf WEnd 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 I hope someone else can find some use for what I did here. I know I have. Link to comment Share on other sites More sharing options...
ptrex Posted March 12, 2007 Share Posted March 12, 2007 @SkInNyWhItEGuY Perfect !! This belongs in the SCRIPT EXAMPLES section !! regards ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
F8LDXSL4P Posted August 22, 2014 Share Posted August 22, 2014 I sometimes get a Line 10 Error: "Variable must be of type "Object" with the USB Backup Script. Anyone else get this? Link to comment Share on other sites More sharing options...
careca Posted August 22, 2014 Share Posted August 22, 2014 i'll answer you in another 7 years from now.. You do realize, autoit has changed from then to now, it's possible there are going to be incompatibilities with those old scripts. cheeroke 1 Spoiler Renamer - Rename files and folders, remove portions of text from the filename etc. GPO Tool - Export/Import Group policy settings. MirrorDir - Synchronize/Backup/Mirror Folders BeatsPlayer - Music player. Params Tool - Right click an exe to see it's parameters or execute them. String Trigger - Triggers pasting text or applications or internet links on specific strings. Inconspicuous - Hide files in plain sight, not fully encrypted. Regedit Control - Registry browsing history, quickly jump into any saved key. Time4Shutdown - Write the time for shutdown in minutes. Power Profiles Tool - Set a profile as active, delete, duplicate, export and import. Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes. NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s. IUIAutomation - Topic with framework and examples Au3Record.exe Link to comment Share on other sites More sharing options...
Michael82 Posted September 2, 2014 Share Posted September 2, 2014 I have been search the net for hours trying to find a way to get this to work. Hopefully some one here can let me know how. I have a USB game pad (HID) and am trying to write the script to launch a program once inserted and then close that program once removed. When i plug in the HID device it doesn't seem to register the same way a USB drive does. Is there anything way that i can do this? I am on a Windows 8.1 box. Thank ins advance for any help Link to comment Share on other sites More sharing options...
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