Windows 8 IShellIconOverlayIdentifier shell扩展无法正常工作

时间:2012-10-31 16:37:52

标签: c++ windows qt windows-shell

我有一个应用程序,我希望有特定文件和文件夹的图标叠加。

为此,我编写了一个实现IShellIconOverlayIdentifier接口的shell扩展。它用c ++ / Qt(activeqt)编写,作为dll连接到有问题的应用程序,使用tcp查询应用程序以决定是否显示图标覆盖。它的构建方式与this大致相同。

它在XP / Vista / 7中运行良好,但在Windows 8中无法正常工作。

在Windows 8中加载了dll。我可以在process explorer中看到它,并且作为调试的一部分,它还将输出记录到文件中,这样我就可以看到发生了什么,并且不能推断出什么。

使用ShellExView我也可以看到它已经注册,而不是禁用,一般来说一切看起来都不错。

类声明或多或少看起来像这样:

class Q_DECL_EXPORT OverlayClass :
    public QAxAggregated,
    public IShellIconOverlayIdentifier{
public:
    // Implements IUnknown
    QAXAGG_IUNKNOWN; 

    JShellOverlayWorking();

    // Implements IShellIconOverlayIdentifier
    STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD* pdwFlags);
    STDMETHOD(GetPriority)(int* pPriority);
    STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);

    //pure virtual from QAxAggregated
    long queryInterface(const QUuid &iid, void**iface); 
};

XP / Vista / 7上发生了什么:

  • 负载上的资源管理器首先调用queryInterface()并获取一个S_OK,如果iid == IID_IShellIconOverlayIdentifier和E_NOINTERFACE用于所有其他iid的
  • 然后继续调用GetOverlayInfo()来初始化东西。获取图标文件路径等。
  • 然后,当shell需要它调用IsMemberOf()时,看它是否应该显示文件或文件夹的图标。

Windows 8上会发生什么:

  • 负载上的资源管理器调用queryInterface()并在iid == IID_IShellIconOverlayIdentifier和E_NOINTERFACE为所有其他iid的
  • 时获取S_OK

没有别的。 queryInterface()被调用,但之后没有任何反应。我可以看到我的应用程序成功连接到shell扩展创建的tcp套接字并且IPC正在工作(我可以在应用程序和dll之间来回发送数据,但是再一次。没有其他事情发生。资源管理器没有使用已实现的接口。

使用以下方式注册dll:

regsvr32.exe shellext.dll

并且还添加了下面的注册表项

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\Shellextname ( value = CSLID )

在Windows 8上进行测试我还添加了以下密钥

HKCU\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved

使用我的shell扩展名CSLID作为名称和数据= Shellextname(如上一个键中所示)虽然这在XP / Vista / 7上似乎并不重要,所以我猜这里也是无关紧要的。

同样,这适用于除Windows 8之外的每个窗口(> = xp)。

我缺少什么?我从哪里去了解?

1 个答案:

答案 0 :(得分:4)

似乎问题是注册表项

HKEY_CLASSES_ROOT\CLSID\{myguid}\InprocServer32
        ThreadingModel = Apartment
指定here

未由regsvr32.exe设置。我想以前的Windows版本如果没有设置则会忽略它,但是Windows 8需要它。手动设置它。