Introduction to Windows Shell Programming
Overview
The Windows Shell provides the graphical user interface for Windows, including the desktop, taskbar, Start menu, and file Explorer. Programming the shell lets you extend or customize these elements, create new user experiences, and integrate tightly with the operating system.
Getting Started
To begin developing shell extensions, you need:
- Visual Studio 2022 or later
- Windows SDK
- Knowledge of COM and C++ (or C# with .NET COM interop)
- Administrator rights for registration
Create a new Win32 Project
in Visual Studio and select DLL as the output type.
Core Concepts
COM Interfaces
Shell extensions are implemented as COM objects. Common interfaces include:
IShellExtInit
– initialization of the extensionIContextMenu
– add custom commands to context menusIShellIconOverlayIdentifier
– custom overlay iconsIPropertyStore
– retrieve or store property values
Registration
Extensions are registered in the Windows Registry under HKEY_CLASSES_ROOT\CLSID
and associated with file types or shell locations.
Sample Code: Simple Context Menu Extension (C++)
#include <windows.h>
#include <shlobj.h>
#include <strsafe.h>
class ATL_NO_VTABLE CSimpleMenu :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSimpleMenu, &CLSID_SimpleMenu>,
public IContextMenu,
public IShellExtInit
{
public:
CSimpleMenu() : m_pszFolder(nullptr) {}
DECLARE_NO_REGISTRY()
BEGIN_COM_MAP(CSimpleMenu)
COM_INTERFACE_ENTRY(IContextMenu)
COM_INTERFACE_ENTRY(IShellExtInit)
END_COM_MAP()
// IShellExtInit
STDMETHODIMP Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID)
{
m_pszFolder = nullptr;
if (pidlFolder)
SHGetPathFromIDList(pidlFolder, m_pszFolder);
return S_OK;
}
// IContextMenu
STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
InsertMenu(hMenu, indexMenu, MF_STRING | MF_BYPOSITION,
idCmdFirst, L"&My Sample Command");
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 1);
}
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO pInfo)
{
if (HIWORD(pInfo->lpVerb))
return E_FAIL;
MessageBox(pInfo->hwnd, L"Sample command invoked!", L"Shell Extension", MB_OK);
return S_OK;
}
STDMETHODIMP GetCommandString(UINT_PTR idCmd,
UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax)
{
return E_NOTIMPL;
}
private:
wchar_t m_szFolder[MAX_PATH];
};
OBJECT_ENTRY_AUTO(__uuidof(CSimpleMenu), CSimpleMenu)
Build the DLL, register it with regsvr32 MyShellExt.dll
, and refresh Explorer. The new menu item appears on right‑click for all files.