Q. I was hoping to find out whether developing add-ons for Windows Explorer is supported using managed code in .NET, and if any samples of this sort of code are available?

Asked by a reader. Answered by the Wonk on January 27, 2003

A.

The Windows File Explorer shell is extensible into a ton of directions, from execution hooks to extend the Run dialog to context menu extensions to augment the built-in context menus for files and folders and that’s just the tip of the iceberg. These extensions almost all have one thing in common: they depend on COM. Specifically; the Explorer uses custom keys in the Registry to fine the shell extensions and then depend on COM functions and interfaces to access the custom functionality. Since you can implement COM components in .NET, theoretically you can implement any kind of COM-based Explorer extension you like.

 

However, practice makes things a lot harder. Almost all of the COM interfaces that need implementing are custom interfaces, which means that they aren’t described via a COM type library. Instead, they’re described in C/C++ header files and there are no tools to turn them into the .NET code that’s required to call and/or implement them. Instead, you have to write that interop code yourself, by hand. For example, a simple context menu extension requires you to implement three COM interfaces, all of which require code like the following to bring them into the managed world:

 

[

  ComImport(),

  InterfaceType(ComInterfaceType.InterfaceIsIUnknown),

  GuidAttribute("0000010e-0000-0000-C000-000000000046") ]

public interface IDataObject {

  [PreserveSig()]

  int GetData(ref FORMATETC a, ref STGMEDIUM b);

  [PreserveSig()]

  void GetDataHere(int a, ref STGMEDIUM b);

  [PreserveSig()]

  int QueryGetData(int a);

  [PreserveSig()]

  int GetCanonicalFormatEtc(int a, ref int b);

  [PreserveSig()]

  int SetData(int a, int b, int c);

  [PreserveSig()]

  int EnumFormatEtc(uint a, ref Object b);

  [PreserveSig()]

  int DAdvise(int a, uint b, Object c, ref uint d);

  [PreserveSig()]

  int DUnadvise(uint a);

  [PreserveSig()]

  int EnumDAdvise(ref Object a);

}

 

And not only do the COM interfaces need importing, so do the dependent data structures, e.g. the STGMEDIUM structure:

 

[StructLayout(LayoutKind.Sequential)]

public struct FORMATETC {

  public CLIPFORMAT cfFormat;

  public uint ptd;

  public DVASPECT dwAspect;

  public int lindex;

  public TYMED tymed;

}

 

Assuming you already know how to build an Explorer extension and you have access to the COM interop goo, the actual implementation of the shell extension is normally pretty anti-climatic.

 

To get started building a COM-based Explorer extension in .NET, I’d first find the documentation and an example for how to do it in raw COM, then look to see if anyone’s yet built the interop layer for the related interfaces and data structures. Google’s Microsoft-specific search page is really good for that, and I used it to turn up a couple examples of Explorer extensions built using .NET:

 

Feedback

I have feedback on this Ask The Wonk answer