WinRAR/WinZip 在資源管理器右鍵選單加入「解壓縮」選項的便利體驗,源於 Shell Extension(殼擴展) 技術。本文以原始碼行數統計工具為例,完整演示如何開發一個 進程內 COM DLL,掛載至資源管理器,對資料夾/檔案右鍵選單新增「原始碼統計」功能,遞迴統計 C/C++ 檔案行數。
IShellExtInit(初始化,取得選取項路徑)與 IContextMenu(建立/處理右鍵選單)介面。HKEY_CLASSES_ROOT\Directory\Shellex\ContextMenuHandlers,即對「資料夾」生效。AppWizard → ATL COM AppWizard → 專案名 SrcCount → 服務類型 DLL(不勾選 MFC,保持輕量)。
CountLines介面 ICountLines 定義兩方法:
GetFileLines(BSTR* pFilePath, int* lines); // 單檔統計
GetFolderLines(BSTR* pFolderPath, int* lines); // 遞迴資料夾統計
單檔: 讀檔 → 掃描 \n 計數(簡易規則,僅示範)。
STDMETHODIMP CCountLines::GetFileLines(BSTR* pFilePath, int* lines)
{
HANDLE hFile = CreateFile((TCHAR*)pFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { *lines = -1; return S_FALSE; }
DWORD size = GetFileSize(hFile, NULL);
BYTE* buf = new BYTE[size];
DWORD read; ReadFile(hFile, buf, size, &read, NULL);
int total = 0;
for (DWORD i=0; i
資料夾: FindFirstFile/FindNextFile 遞迴遍歷,過濾 .c/.cpp/.h 副檔名,累加單檔結果。
在 COM Map 加入:
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
從 LPDATAOBJECT 擷取選取項完整路徑(CF_HDROP 格式),保存至成員變量 m_pszPath。
// 1. 新增選單項
QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
InsertMenu(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, _T("原始碼統計(&S)..."));
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 1); // 1 個項目
}
// 2. 狀態列提示文字
GetCommandString(UINT idCmd, UINT uFlags, UINT* pwReserved, LPSTR pszName, UINT cchMax)
{
if (uFlags == GCS_HELPTEXT) lstrcpy(pszName, "統計資料夾內 C/C++ 原始碼行數");
return S_OK;
}
// 3. 執行命令
InvokeCommand(LPCMINVOKECOMMANDINFO pici)
{
// 驗證命令 ID(支援 ANSI/Unicode 雙模式)
// 顯示等待游標 → 呼叫 GetFolderLines → 彈出 MessageBox 顯示結果 → 還原游標
}
SrcCount.dll,複製至 C:\Windows\System32(或任意目錄)。regsvr32 SrcCount.dll(VC 建置事件可自動化)。HKEY_CLASSES_ROOT\Directory\Shellex\ContextMenuHandlers\ 新建項 SrcCount,預設值設為元件 GUID:{548773BA-874E-4C02-9DC7-B7A096772C7D}。

IContextMenu2/3、Owner-draw)參考 WinRAR 風格。專案在 VC6/XP 下編譯通過,相容 Win9x/NT/2000/XP。完整原始碼附件下載。