Thursday, May 28, 2009

Windows Selected Filenames

For the longest time I could be in a folder and want to figure out a way to add a set of selected filenames to the clipboard, this might sound easier then it really is, here's my journey.

There are/were 3 barriers for me:
1. I don't know the Windows API verywell, so I can't do it that way (yet)
2. I can't pass multiple filenames to a program (again falling into the "api" factor)
3. Because of # 2, I can't clear the clipboard and then add the item because when the script is ran it will only add the passed in parameter to the clipboard, and since I haven't figured out how to pass multiple filenames via parameters, so we'll have whatever was IN the clipboard remain.

I decided that perl might be a fun way to do this, here is my plan of attack,
1. Create a perl script that takes whatever is passed to it, and adds it to the clipboard (a.k.a appends it).
2. Add this item to the right click menu (similar to the way we added the command line prompts)

Let's get started.

Here is the code I'm using and I'll explain it line by line after:
#! perl use WIN32::CLIPBOARD;
$CLIP = Win32::Clipboard();

@sp = split(/\\/, $ARGV[0]);
$text = $CLIP->Get();
$string = $sp[@sp-1];
$text = $text . "\n" . $string;

First we declare:

This is so we can use Windows Clipboard functions

Next is
$CLIP = Win32::Clipboard();
Here we setup the $clip as a clipboard object.

@sp = split(/\\/, $ARGV[0]);

Here we split the passed in parameter (windows passes the entire path to the filename)
up by the \ character.

$text = $CLIP->Get();
We go get the contents of the clipboard

$string = $sp[@sp-1];
Here we store off the last item of the split up array which happens to be the filename only, no path.

$text = $text . "\n" . $string;
Here we append the filename to the original clipboard contents.

This is the last line, and all it does is take the text string we created by appending our filename to the original contents, and sets it to the clipboard.

Now what I have been doing is starting a folder on my C drive called batch that I stick all my context menu executable items.

Finally we'll follow the steps outlined in Command Prompt to add the selection to a folder
1. Open an explorer window, this can be accomplished by either pressing "Windows key + E" or just opening a folder.
2. Select Tools Folder Options,
3. Click the Tab File Types
4. Select Folder
5. Select Advanced
6. Select New
7. For Action name, Just name it something you'll remember like "Copy Filenames"
8. For the application used to perform this action enter the path to your perl script you created above
9. Select Ok's to exit.
10. Try it out, now go to a folder and right click on it and select whatever you named your action.

Now in order to see it show up on ALL files, you will need to do a bit of Registry editing,
Here's the steps:
1. Windows key + r (Or just get to the run dialog using start then run)
2. type in regedit and hit enter
3. Save your current registry (in case you mess up) by using export under the file menu.
4. Navigate to HKEY_CLASSES_ROOT
5. The first entry is *,expand this
6. If there is a folder called shell expand it, if not you can create one by right clicking on the * folder and selecting New then Key, make sure to name it shell.
7. On the shell folder right click and select New then Key, Name it whatever you called your action in the previous step for folders.
8. On the folder you just created add a new key once more and call it command.
9. Now in the right side of the window edit the (default) item by double clicking on it,
10. Enter in cmd /c %1
(Mine looks like this:
cmd /c c:\batch\ %1)
11. Click ok, and you have updated your registry

Try it out now!

1. If you select LOTS of items and try to add it, you could run into problems because windows will have to start one instance for each file, this works great for 0-20ish files, once you start getting higher, windows will ask you if you're sure that you want to do this.

2. Also I have run into the problem if I have a folder selected AND a file selected the tool will only add one or the other to the clipboard, haven't quite figured that one out either.

If you have any other ideas on how to implement this let me know, I couldn't seem to find this anywhere on the net but who knows, maybe someone has posted it somewhere, and I have yet to find it, either way leave a comment and let me know how it works.

No sooner then after having this little "trick" in my bag for a couple months and FINALLY posting about it, do I find an alternate way to do this that might work alot better, it won't open numerous instances of the program so it'll be alot quicker. I'll post an "updated" post in the near future once i work all the bugs out.

UPDATE II:You can now check it out here