图标处理程序 Shell 未调用扩展
Icon Handler Shell Extension not called
我用VS2015和ATL项目向导写了一个Shell扩展Icon handler。我创建了一个 COM 对象来公开 IPersist 和 IExtractIcon 接口。当我查看特定文件类型的注册表项时,我可以看到处理程序已注册。这是 class 的样子:
class ATL_NO_VTABLE CIconHandlerExt :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CIconHandlerExt, &CLSID_IconHandlerExt>,
public IIconHandlerExt,
public IPersistFile,
public IExtractIcon
{
public:
CIconHandlerExt()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_ICONHANDLEREXT)
DECLARE_NOT_AGGREGATABLE(CIconHandlerExt)
BEGIN_COM_MAP(CIconHandlerExt)
COM_INTERFACE_ENTRY(IIconHandlerExt)
COM_INTERFACE_ENTRY(IPersistFile)
COM_INTERFACE_ENTRY(IExtractIcon)
END_COM_MAP()
// IIconHandlerExt
public:
// IExtractIcon
STDMETHODIMP GetIconLocation(UINT uFlags, LPTSTR szIconFile, UINT cchMax, int* piIndex, UINT* pwFlags);
STDMETHODIMP Extract(LPCTSTR pszFile, UINT nIconIndex, HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize);
public:
// IPersistFile
//xxxSTDMETHOD(GetClassID)(CLSID*) { return E_NOTIMPL; }
STDMETHOD(GetClassID)(CLSID *pClsId) { *pClsId = CLSID_IconHandlerExt; return S_OK; }
STDMETHOD(IsDirty)() { return E_NOTIMPL; }
STDMETHOD(Save)(LPCOLESTR, BOOL) { return E_NOTIMPL; }
STDMETHOD(SaveCompleted)(LPCOLESTR) { return E_NOTIMPL; }
STDMETHOD(GetCurFile)(LPOLESTR*) { return E_NOTIMPL; }
STDMETHOD(Load)(LPCOLESTR wszFile, DWORD /*dwMode*/)
{
USES_CONVERSION;
lstrcpyn(m_szFilename, OLE2CT(wszFile), MAX_PATH);
return S_OK;
}
protected:
TCHAR m_szFilename[MAX_PATH]; // Full path to the file in question.
};
OBJECT_ENTRY_AUTO(__uuidof(IconHandlerExt), CIconHandlerExt)
我使用 this post 中的说明开始调试会话。也就是说,我单击任务栏,按 Alt-F4,按 Ctrl-Alt-Shift-Escape,然后启动我的调试器会话,将 Windows Explorer 指定为命令目标。我设置断点并导航到测试文件。
我的处理程序从未加载,因为断点未命中,他们说
“The breakpoint will not currently be hit. No symbols have been
loaded for this document.”
谁能解释为什么我的扩展没有加载?
这个问题已经解决了。
Shell 扩展需要更新向导生成的注册表脚本以识别应该用于特定文件类型的处理程序。我没有注意我正在更新的密钥(从注册表脚本中)并更新了 wrong 密钥。就我而言,我尝试为其添加处理程序的文件类型是“mcam”。所以,我更新了“HKCR.mcam”键。这是不正确的,因为此初始键的目的是(通过“mcamFile”子键)指向确定要加载的处理程序的实际注册表项。一旦我更改了脚本以更新“HKCR\mcamFile”键,处理程序就被加载了,我就可以调试我的代码了。
我用VS2015和ATL项目向导写了一个Shell扩展Icon handler。我创建了一个 COM 对象来公开 IPersist 和 IExtractIcon 接口。当我查看特定文件类型的注册表项时,我可以看到处理程序已注册。这是 class 的样子:
class ATL_NO_VTABLE CIconHandlerExt :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CIconHandlerExt, &CLSID_IconHandlerExt>,
public IIconHandlerExt,
public IPersistFile,
public IExtractIcon
{
public:
CIconHandlerExt()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_ICONHANDLEREXT)
DECLARE_NOT_AGGREGATABLE(CIconHandlerExt)
BEGIN_COM_MAP(CIconHandlerExt)
COM_INTERFACE_ENTRY(IIconHandlerExt)
COM_INTERFACE_ENTRY(IPersistFile)
COM_INTERFACE_ENTRY(IExtractIcon)
END_COM_MAP()
// IIconHandlerExt
public:
// IExtractIcon
STDMETHODIMP GetIconLocation(UINT uFlags, LPTSTR szIconFile, UINT cchMax, int* piIndex, UINT* pwFlags);
STDMETHODIMP Extract(LPCTSTR pszFile, UINT nIconIndex, HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize);
public:
// IPersistFile
//xxxSTDMETHOD(GetClassID)(CLSID*) { return E_NOTIMPL; }
STDMETHOD(GetClassID)(CLSID *pClsId) { *pClsId = CLSID_IconHandlerExt; return S_OK; }
STDMETHOD(IsDirty)() { return E_NOTIMPL; }
STDMETHOD(Save)(LPCOLESTR, BOOL) { return E_NOTIMPL; }
STDMETHOD(SaveCompleted)(LPCOLESTR) { return E_NOTIMPL; }
STDMETHOD(GetCurFile)(LPOLESTR*) { return E_NOTIMPL; }
STDMETHOD(Load)(LPCOLESTR wszFile, DWORD /*dwMode*/)
{
USES_CONVERSION;
lstrcpyn(m_szFilename, OLE2CT(wszFile), MAX_PATH);
return S_OK;
}
protected:
TCHAR m_szFilename[MAX_PATH]; // Full path to the file in question.
};
OBJECT_ENTRY_AUTO(__uuidof(IconHandlerExt), CIconHandlerExt)
我使用 this post 中的说明开始调试会话。也就是说,我单击任务栏,按 Alt-F4,按 Ctrl-Alt-Shift-Escape,然后启动我的调试器会话,将 Windows Explorer 指定为命令目标。我设置断点并导航到测试文件。
我的处理程序从未加载,因为断点未命中,他们说
“The breakpoint will not currently be hit. No symbols have been loaded for this document.”
谁能解释为什么我的扩展没有加载?
这个问题已经解决了。
Shell 扩展需要更新向导生成的注册表脚本以识别应该用于特定文件类型的处理程序。我没有注意我正在更新的密钥(从注册表脚本中)并更新了 wrong 密钥。就我而言,我尝试为其添加处理程序的文件类型是“mcam”。所以,我更新了“HKCR.mcam”键。这是不正确的,因为此初始键的目的是(通过“mcamFile”子键)指向确定要加载的处理程序的实际注册表项。一旦我更改了脚本以更新“HKCR\mcamFile”键,处理程序就被加载了,我就可以调试我的代码了。