Showing posts with label selections. Show all posts
Showing posts with label selections. Show all posts

Monday, June 8, 2009

Windows Selected Filenames Pt II

Welcome back, well as we all know, in the words of my good friend Phil:
"But with all programming/design problems – there are a multitude of unique methods that may be employed to removed the dermal layer of the felinus domesticus"
If you don't know how to setup a "right click" menu item for files and folders I would recommend checking out the following posts: Windows Selected Filenames, Command Prompt

Lets get on with it, This "version" of the selected filenames will use the same steps to get it up and running, (right click menu), but the only difference is that now when we have our script setup we'll copy the files to the clipboard, then deslect the files and right click on a single filename and select your copy filenames script, Lets get into the meat of this script,

#! perl
use WIN32::CLIPBOARD;

$text = "";
$CLIP = Win32::Clipboard();

if ($CLIP->IsFiles())

{

@files = $CLIP->GetFiles();

foreach $file (@files)

{
@sp = split(/\\/, $file);

$text = $text .$sp[@sp-1] . "\n";
}
$CLIP->Set($text);

}
Breaking it down again:

First we declare:
use WIN32::CLIPBOARD;
This is so we can use Windows Clipboard functions

Next is
$text = "";
We want a clean text string.

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

Next,
if ($CLIP->IsFiles())
What this is doing is checking that there are "files" in the clipboard, we want this because otherwise we'll try to write "nothing" to the clipboard and I'm sure that's not a problem, but if for some reason you really didn't mean to do this and you already had text in the clipboard then it won't overwrite your text clipboard contents, either way it won't write to the clipboard if you don't have any files in the clipboard, you can remove this if you want but I haven't tested it out, it may work just fine.

Then,
@files = $CLIP->GetFiles();
This chunk of code goes out and gets the files in the clipboard, and stores them in an array.

Next,
foreach $file (@files)
So what we're going to do is run the next couple of lines for each file (or in this case we'll be grabbing the filename)

Then,
@sp = split(/\\/, $file);
This line splits the "filename" up into segments if you were interested in the whole pathname you could omit this step and just assign the $text variable to whatever $text contained and the $file variable plus "\n", so you get each filename on a new line.

Next,
$text = $text .$sp[@sp-1] . "\n";
This takes the split up line above and grabs the last bit of it, which happens to be the actual filename. Remember if you wanted the entire pathname you could use the $file variable like so,
$text = $text . $file . "\n";

Finally,
$CLIP->Set($text);
This line sets your newly created text to the clipboard!

Give it a try and let me know how it works out for you!

I'm sure this isn't the last post about this subject, as always things are always improving, I am constantly thinking of a way to cut back on the amount of steps to run this little "tool" my plan is to eventually "simulate" the keystroke to "copy" the files then copy the filenames, not sure how to go about it, without running multiple instances, I'm sure hotkeys will be a big help on this, either way I'll be improving this script again in the future...Stay tuned I'm certain there will be more posts on getting this working better.

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;
$CLIP->Set($text);

First we declare:
use WIN32::CLIPBOARD;

This is so we can use Windows Clipboard functions

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

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

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

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

Next,
$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.

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

Finally
$CLIP->Set($text);
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\filelisting_selection.pl %1)
11. Click ok, and you have updated your registry


Try it out now!

Limitations:
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.

UPDATE:
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