Download source files - 270 Kb
Introduction
As a Windows programmer, one of the big headaches for me has been referencing fully qualified
file paths. A file buried deep within the filesystem becomes a bear to deal with, as neither
I nor any other programmers I know want to manually type
"C:\Windows\System32\Drivers\SomeDriver\AnotherSubFolder\YetAnother\Will-It-Ever-End\MyFile.txt" time after time.
This annoyance sent me on my initial foray into the land of context menu extensions, in the
summer of 1997. I initially implemented this context menu extension as a MFC Dll, which got
the job done, but it certainly wasn't pretty. Later, in May of '99, in the process of trying
to familiarize myself with the ATL and the STL, I realized that I could make a much cleaner
and more efficient version using ATL. So that's just what I did.
This extension may seem to be derivative of Glenn Carr's recent article
"Shell Extension to Copy Full Filename Path" (See the Article), but was developed independently (aside from some last-minute changes to GetCommandString to correctly deal with Unicode). Mine is simply another way to do pretty much the same thing, with some extras. I decided to post this alternative because it adds a few programmer-friendly features. There has also been a PowerToy in existence for quite a while that adds an option to the "Send To" menu allowing you to do basically the same thing, but once again,
I thought that this implementation adds enough to make it worth posting.
One hassle when dealing with file paths in C or C++ (or other similar languages, such as Perl)
is the way that these languages deal with literal strings. They treat the backslash character
as an escape sequence to insert special characters into the string (e.g "\n" for newline). In
order to insert a single backslash into a literal string, two backslashes must be included in
the code (e.g. "C:\\config.sys"). One can imagine how this would be a headache when dealing
with a file that resides deep within a jumble of subdirectories. Another problem when dealing
with file paths arises when dealing with legacy applications that don't take too kindly to
long filenames or filenames with spaces.
In addition to simply copying a file path to the clipboard, this extension offers
functionality to remedy the above problems. By simply holding down the Control key while
selecting the menu item, the "C-Friendly" path will be copied to the clipboard
(e.g. "C:\\Windows\\System32\\user32.dll"). Holding down the Shift key will copy the short
"DOS-Friendly" path (e.g. "C:\Progra~1\Multim~1\sound.wav"). And should the desire strike
you, you can even hold down both with predictable results. The extension also sports multiple
selection capability, file and/or directory selections, as well as anti-lock brakes and a
no-scratch finish. Also, as Glenn Carr mentions in his article, with no programming effort
on my part, running the extension on a shortcut copies the shortcut's target path to the
clipboard.
Code
The code consists of an ATL DLL project with a single class, CCopyPathContextMenu
. Like all context menus, it implements the
IContextMenu
and IShellExtInit
interfaces. It also
supports the IContextMenu2
and IContextMenu3
interfaces,
but does not use their added functionality.
IShellExtInit::Initialize
- Culls the selected file and directory names from the
OLE data object and adds them to a STL list of basic strings.
IContextMenu::QueryContextMenu
- Adds the new menu item to the context menu.
IContextMenu::GetCommandString
- Provides help text for Explorer to display on
the status bar.
IContextMenu::InvokeCommand
- Called when the user selects our menu item, copying
the directory and file names from the STL list filled in the Initialize
function
to the clipboard.
Build Versions and Registering
There are several build configurations you need to consider in the project:
- bin\ReleaseUMinDependency\ - Unicode
- bin\DebugU\ - Unicode
- bin\ReleaseMinDependency\
- bin\ReleaseMinSize\
- bin\Debug\
- bin\ReleaseUMinSize\ - Unicode
To register the file, simply select the appropriate version of the DLL (remember that Unicode
builds will not work correctly on Win95/98), copy it to an appropriate location (Windows
System Directory recommended), and run "RegSvr32 CopyPathExt.dll" from the command line.
The item "Copy Path to Clipboard" will now appear when you right-click on files or
directories!