Saturday, June 10, 2006

CopyFilenames Shell Extension

Overview

CopyFilenames is a free Shell Extension for Windows Explorer which allows you to copy the full filenames of one or more files to the clipboard. You can then paste the filename(s) into another document or email, or even directly into the filename box in your web-browser. No more searching for that file!

Download

CopyFilenames should work on all versions of Windows. No other files are needed. Download the Windows Installer package here [SetupCopyFilenames.msi - 283Kb] - follow the instructions in the setup installer.

Background

When browsing files with the Windows Explorer interface, I find I often want to copy/paste the name of a file or group of files.

For example, when uploading an image or document in my webbrowser, without CopyFilenames, I would click Browse... and then be forced to traverse the directory tree to find the file, which I can see in the Explorer window on screen!

Or perhaps I want to make reference to a group of files in a document. I want to be able to grab their filenames quickly, without resorting to a nasty command prompt dir *.jpg > filenames.txt command.

Source Code

The code was written in Delphi 5, because it has great support for simple COM/ActiveX objects, and doesn't require the .Net Framework, so CopyFilenames can run on almost every version of Windows.

The gubbins of the source is as follows:

  // ...

  // Render the data referenced by the IDataObject pointer to an HGLOBAL
  // storage medium in CF_HDROP format.
  Result := lpdobj.GetData(FormatEtc, StgMedium);
  if Failed(Result) then
    Exit;

  try

    // We collect a list of filenames for all items selected 
    // and store them in a string list object for later use.
    //
    //
    numFiles := DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0);
    _InitFilesList(numFiles); // preps the list with the correct number of slots

    for i:= 0 to numFiles-1 do
    begin
      filenameLength := DragQueryFile(StgMedium.hGlobal, i, nil, 0);
      DragQueryFile(StgMedium.hGlobal, i, LFileNameBuffer, SizeOf(LFileNameBuffer));
      filename := LFileNameBuffer;

      FFilenames[i] := filename;
    end;

    Result := NOERROR;

  finally
    ReleaseStgMedium(StgMedium);
  end;

  // ...

The details are pretty arcane, but most of the heavy-lifting is done by the Windows Explorer interface and the Shell handlers, which provide us with all the information we need. We convert it to Delphi-style strings, then copy the info up the clipboard, with each filename separated by a newline.

Any comments welcome.

Thursday, February 23, 2006

FilenameFormat - generate time-stamped filenames

FilenameFormat.exe is a small utility to format filenames based on the current date and time. It's useful for batch scripting, for example, creating folders or files on a regular basis with a time- or date-stamp.

It uses C#-style "curly brace" formatting. The help outpur explains all:

> FilenameFormat.exe

FilenameFormat - formats filenames with current date/time info.
Copyright (c) 2006 DevDoctor.com

Usage: FilenameFormat <filename_pattern> <datetime_pattern> [<copy_target>]

       where:
       <filename_pattern> is the pattern of the target filename
       <datetime_pattern> is the pattern of the date
       <copy_target> (optional) copy this file to new file with preceeding pattern

Both parameters use C#-style string formatters.

Examples:
       'FilenameFormat datafile_{0}.dat yyyy-MM-dd'
               -->     datafile_2008-02-04.dat
       'FilenameFormat day_{0}.dat dd C:\temp\day.dat'
               -->     day_04.dat; copy 'C:\temp\day.dat' to 'C:\temp\day_04.dat'

You are free to use this utility as you wish.

Tuesday, January 10, 2006

Simple Redirect

Overview

Simple Redirect performs a redirect from one IIS Virtual Directory to another URL. Nothing fancy, it just does that!

Useful for situaltions where the main part of your website is located under a sub-folder (i.e. Virtual Dir), and all requests for the root of the site should go to those pages.

Example

You have a webserver configured at http://www.example.com/, but the main part of the site lives at http://www.example.com/pages/. You also have a CRM package installed at http://www.example.com/crm/. You cannot therefore perform a redirect at the IIS level for the whole domain, as the other applications will not be available.

Anyone visiting the plain http://www.example.com/ address is assumed to really want http://www.example.com/pages/, so is directed there, but those who visit the CRM pages directly receive those as expected.

Source Code

Here is the important source code:

protected void Page_Load(object sender, EventArgs e)
{
    string targetURL = ConfigurationManager.AppSettings["TargetApplicationURL"];
    string targetName = ConfigurationManager.AppSettings["TargetApplicationName"];
    Response.Redirect(targetURL, true);
}

The actual URL to redirect to is taken from the web.config file.

The code was tested with ASP.NET 2.0, but should be easily modifiable for version 1.1