14 May 2008

A number of people have asked me how to customise their USB stick so that it does different things depending on the machine into which the stick is inserted.  Perhaps when you insert the stick into one PC you need it to synchronise with a folder or make a backup of the stick, but when inserted into any other PC you need it to run an application or do something else.

In order for something automatic to happen when the USB stick is inserted into a computer you need to have a file called autorun.inf bottom directory of the stick (which we call the root).  When the stick is inserted into a machine the PC will bring up a menu asking what to do by listing a few different actions.  The autorun.inf is just a text file that will define default action offerred to the user in the menu. The autorun.inf file on my stick comprises of the following text:

action=Launch Matt Parkins' Portable

Which is pretty simple, but for those that want a run through: line 1([AutoRun]) doesn't do much - it is just a pretty label (it is actually a section header so that the .inf file follows the .inf/.ini file format correctly but since there is only 1 section in an autorun.inf then it is a bit redundant);

Line 2 (open=autorun.bat) specifies the file to run if this option is selected;

Line 3 (action=Launch Matt Parkins' Portable) gives the title for this option - it could be anything you want - it is just a label;

Line 4 (icon=PortableRoboForm.exe) specifies the file that contains the icon for the menu option and the stick when viewed through Windows Explorer - it could be an .ico or a binary with an icon built in (such as an .exe);

and finally line 5 (label=MattParkins) specifies the label for this drive, again when viewed through Windows Explorer. Obviously to get the stick to run something else you'd change the options as appropriate.

Now, in order to do different things depending on which computer the stick is inserted into (or even run multiple programs on any computer) you need to be able to detect which computer you're running on and issue multiple commands. Batch files are quite easily up to the task so I created the file autorun.bat at the root of the stick, and, as you saw earlier, I specified this file to run in autorun.inf line 1.

So autorun.bat is a batch file, like autorun.inf it is just a text file but this file contains a bunch of commands, rather than just information. If you wanted to run multiple programs at start up (I run roboform portable AND 8start - a portable apps menu system), then the following autoexec.bat would be a good example:

@echo off
start portableroboform.exe
start portableapps8start8start.exe

Ok, so this is quite simple.  The batch file will be executed in what is called a console window - a black screen with white text on it usually.  Each command is then executed in sequence: @echo off merely means that these commands are not echoed to the console making it look a bit neater. The next two lines execute portableroboform.exe and portableapps8start8start.exe. It is important to use the start command as otherwise the batch file would wait for each program to complete before running the next command which would be bad - ie, since both programs stay resident it would never get to the next command. If however you do want the command to complete before moving to the next command then either miss out the "start" command or specify /nowait as an option.

That's an ultra simple batch file. But what if, when you insert your stick into your own PC, you want to sync your robo passcards (one set contained on your stick, another near identical set on your PC but they may have the odd change/addition). What if you make a backup / update a mirror of your stick on your PC every time you insert it? Of course you don't want to do those things when you insert your stick onto someone elses PC, just your own. Well here's what I do. I create a unique file that will not be found on any one elses PC in the location that you specify. Perhaps put it in your my documents folder - I called mine roboform_homemachine.txt. The file itself is an empty file as the batch file is merely going to detect whether the file exists - it isn't actually going to read its contents. The name of the file is arbitrary - I could have called it slkfdhalskfdhal.pah for all the computer cares, but I named it something slightly sensible so that I wouldn't accidentally delete it when spring cleaning. Ok, here's a more complicated batch file as an example:

@echo off
if not exist "C:Documents and SettingsMattMy Documentsroboform_homemachine.txt" goto ALLMACHINES1

"syswindows 2003 server resource kitrobocopy.exe" "My RoboForm DataMatt" "C:Documents and SettingsMattMy DocumentsMy RoboForm DataMatt" /E /r:0 /w:0 /XJ
"syswindows 2003 server resource kitrobocopy.exe" "C:Documents and SettingsMattMy DocumentsMy RoboForm DataMatt" "My RoboForm DataMatt" /E /r:0 /w:0 /XJ

start portableroboform.exe
start portableapps8start8start.exe

if not exist "C:Documents and SettingsMattMy Documentsroboform_homemachine.txt" goto ALLMACHINES2

"syswindows 2003 server resource kitrobocopy.exe"  C:arcusb /MIR /Z /XJ /R:0 /W:0 /XD data_notbackedup

echo All done!

So the first thing to do in this batch file is work out if we're on my own PC, and that is done through the "if not exist" command, which checks to see if the specified file does not exist, and upon failing to find the file goes to the specified label (ALLMACHNIES1). Obviously this is not totally foolproof as if you have a friend called matt they may just create the same file on their PC just to play with your mind - that aside it should work fine. If the file does exist, ie we're on the PC where we want to do something special, then the command flow goes to the next line. These next 2 lines copy new & updated files from a folder on the stick to a folder on the computer using a very clever piece of software called robocopy.exe. Robocopy has nothing to do with roboform, it is actually part of the windows 2003 server resource kit that can be downloaded from microsoft (google it). I do all my command prompt copying using robocopy (which is so named apparently meaning Robust Copy).  You could use "xcopy" or just "copy" if you wished.

I won't run though each of the options but basically the line ("syswindows 2003 server resource kitrobocopy.exe" "My RoboForm DataMatt" "C:Documents and SettingsMattMy DocumentsMy RoboForm DataMatt" /E /r:0 /w:0 /XJ) the first speachmarked bit means run robocopy and the rest is information passed into that program. So it copies new and updated files from "My RoboForm DataMatt" into "C:Documents and SettingsMattMy DocumentsMy RoboForm DataMatt" (/E means new & updated files, /r:0 means no retries on fail, /w:0 means wait zero seconds between retries (redundant really), and /XJ means exclude junction points).  Of course, you could be doing anything here: copying files, synchronising, downloading webpages, whatever...

It looks complicated but as with most things computery if you take a deep breath and work though them one a time you'll be just fine. The next line does the same thing in reverse as /E option means that anything that is newer on the PC would not be overwritten by older stuff on the stick (VERY useful). The only drawback with this method is that if you want to delete something you have to delete it from both the stick AND the PC. See later if you merely want a folder on your PC to be an exact copy of something on your stick.

We then hit the first label marker :ALLMACHINES1. These label markers don't do anything, they just there so that they can be used in "goto" commands and if you weren't sent there by an earlier "goto" command then it is just ignored. Therefore regardless of whether I'm on my own machine or someone else's the commands following this label are run by all machines. So here is where we kick off any programs we want to run that are not reliant on other operations completing. The first one, portableroboform, uses data that we copied either to or from my home PC so it is good for that copy operation to complete before running portableroboform - that operation takes under a second to complete too so I don't mind waiting! I do a full backup of the stick later, and, depending on how much new & newer data there is on the stick that can take almost no time at all, or 5 minutes if I have a lot of new stuff (I have a 4GB stick), so I do the full backup / mirror of the stick after running these start up programs so that I can get on and use them while the mirror happens in the background. Ok, onward, lets see how I do that!

Obviously I only want to back up to my own PC so we need to find out again if we're on my PC or someone else's using exactly the same "if not exist" statement from earlier, but this time with a different label (ALLMACHINES2). If we used the same label as before we'd just go around in circles - or an infinite loop as we call them.

So the next statement ("syswindows 2003 server resource kitrobocopy.exe" C:arcusb /MIR /Z /XJ /R:0 /W:0 /XD data_notbackedup) again calls robocopy but this time using the /MIR command - or "mirror mode". This is a clever command that creates an exact copy of the folder you specify "" into "C:arcusb". The options I've put in there also specify that it should copy all subdirectories also whilst not including a subdirectory called data_notbackedup which is a subdirectory into which I place things that I don't want backed up (say I'm just moving a large file from a to b and it isn't that important really!). The beauty of /MIR mode is that it also deletes files on the destination directory that do not exist at the source. So if I delete a file from my stick it will be deleted from the backup also. In other words, the destination directory is a precise mirror image of the stick, and it does it with the least effort required - it only copies what it needs to (as opposed to deleting the entire directory and starting again which is the normal method!). Clever.

Finally we hit the control label :ALLMACHINES2 and then all machines display a little message at the console saying "all done" which, because there is no pause, disappears as the command prompt closes itself once all the commands in the batch file have been executed.  And that, as they say, is that!

blog comments powered by Disqus