Actions on USB Recognition

I endeavor to keep a sort of "Chinese Wall" between my work and personal computing and, as such, try not to install or store personal stuff on the company hardware. I generally make an effort to keep stuff like music files and media players on thumb drives or, for larger stuff, USB drives. Sometimes, to save a few steps, I like to automatically kick off related activities when I insert or remove USB devices. This is how I do it.

First, get yourself some AutoHotKey. You'll need it for this, and oh-so-many-other things. Be sure to create your own "startup.ahk" file, as you'll need somewhere to hang this.

Let's start from back and work towards initiation.

Paste this function into your startup script:

CheckUSBDrives:
DriveGet, nlist, list, REMOVABLE
If StrLen(nlist) < StrLen(dlist) ; drive removed
{
        ; Look for the removed drive drive
        Loop Parse, dlist
                IfNotInString, nlist, %a_LoopField%
                {
                        if(%a_LoopField% = K)
                        {
;Do stuff that needs to happen when you remove a drive
;Like close an app, lock your PC, or turn down your music,
                        }
                }
}
If StrLen(nlist) > StrLen(dlist) ; drive added
{
        ; Look for the new drive
        Loop Parse, nlist
                 IfNotInString, dlist, %a_LoopField%
                 {
                        if(%a_LoopField% = E)
                        {
;Do stuff that needs to happen when you add a drive
;Like launch an app, or update a log
                        }  
                 }
}
dlist=%nlist%
return

So, this is what's happening...

CheckUSBDrives:
DriveGet, nlist, list, REMOVABLE

This declares the procedure, and then gets the list of currently attached removable drives. It assignes them to the local variable

If StrLen(nlist) < StrLen(dlist) ; drive removed
{
        ; Look for the removed drive drive
        Loop Parse, dlist
                IfNotInString, nlist, %a_LoopField%
                {
                        if(%a_LoopField% = K)
                        {

This compares the new list to the last list of drives we had and, if it's less, it looks for a specific drive letter. In this case, it's "K". A Windows PC will almost always remember how it mounted a device last time, and will assign it the same drive letter. In this way, you can identify the actual device inserted or removed. For me, "K" always means "thumb drive" (at least on the home PC) and, since it's attached to my keys, can usually be used as a proxy for presence.

And the reverse, for a newly added device ...

If StrLen(nlist) > StrLen(dlist) ; drive added
{
        ; Look for the new drive
        Loop Parse, nlist
                 IfNotInString, dlist, %a_LoopField%
                 {
                        if(%a_LoopField% = E)
                        {

Oh, and this ...

dlist=%nlist%
return

... just updates the global "dlist" value, the baseline for comparing changes, to the new value you just created.

Now, we'll need a function to call that:

notify_change(wParam, lParam, msg, hwnd)
{
        ;Give the drive a moment to register
        SetTimer, CheckUSBDrives, -2000
}

The only trick here, and you may need to adjust this based upon your own hardware, it the 2 second delay added to give the PC time to recognize the device and add the the mount.

And, finally, the trigger to get all of this rolling. Post this outside of any function, procedures, or shortcuts in the "global" area.

notify_change(wParam, lParam, msg, hwnd)
DriveGet, dlist, list, REMOVABLE
OnMessage(0x219, "notify_change")

Here, we get the first list of mapped drives from when the script starts up. "dlist" is set to the value of "nlist" every time the core procedure runs, so it's global and always up to date.

"OnMessage" sets a watch for any change in attached USB devices and, when it finds one, it runs "notify_change", which then runs "CheckUSBDrives".

And that's basically it. Go forth and be efficient. Or even overly optimized.

Thanks goes out to VxE who posted the original inspiring post many moons ago.