MS Windows Shell Hacks


What's here
Inspired by tortoisecvs and tortoisesvn, I put together a couple context menu extensions of my own. Because I'm using functions from tortoisesvn (and an icon from 7zip), this code is necessarily under the GNU GPL, though, if viral licensing bothers you, it wouldn't really be that hard to rewrite all the tortoisesvn functions.

The programs are very simple ATL / COM shell extensions in the style of the old copy path extension on codeguru; however, they've been updated to have improved icon quality using techniques from the bitmap extension demo on code project, as well as a few choice pieces of the tortisesvn source. I've implemented them all in msvc7, which will be either annoying or helpful depending on what side of the fence you live on.

Here's source code for two simple context menu extensions which just call external command line programs; and here's an NSIS installer for the same. The installer is included mostly for my own convience, without a copy of the command line scripts that they call, the context menus won't actually do anything.


Notes on building context menus with COM and ATL
  (aka, The document I wish I had had 48 hours ago.)
Good example code / tutorials can be found at:

http://www.codeguru.com/Cpp/COM-Tech/shell/article.php/c1315/
http://www.codeproject.com/shell/overlayicon.asp
http://www.codeproject.com/shell/ShellExtGuide1.asp

For those of you with aversions to the microsoft SDKs: don't be afraid of the MSVC ATL wizards, working with them is really the only way to get this sortof thing done.

Also, buy/borrow/steal a copy of this book:
Visual C++ Windows Shell Programming (it's out of print, but there are a lot of copies floating around on Kad. You're interested primarily in the second half of chapter 15.)

And don't be afraid to poke around in the tortoise[cvs,svn] source, it's fairly well organized and readable.

Cleaning up the registry: Use `regsvr32 /u` to take out the old registry entries for your dll before messing with the .rgs file.

Close all copies of explorer before recompiling -- otherwise you may not be able to write to the .dll.


Notes on msvc7
All of the preceding tutorials are in msvc6, and so if you decide to work with msvc7, life will be slightly more complicated. The wizards have changed a bit, and by default you'll be using a different version of ATL.

Things that msvc7 coders should watch out for in particular:
  • You'll need to increase the priority of the PlatformSDK includes to dodge the "no GUID has been associated with this object" bug that otherwise may come when defining COM_INTERFACE_ENTRY's.

  • When creating a new ATL Project, disable 'Attributed' and enable MFC support.

  • You'll need to get resource instances from the application, defined in your main cpp file, instead of using _Module. I've been doing this by exporting a little helper function:
    HINSTANCE get_hinst() { return theApp.m_hInstance; }