不显示壳牌覆盖图标

时间:2012-10-02 13:05:07

标签: c# .net shell icons overlay

我正在尝试为我的应用实现自定义叠加图标。这是(简化)代码:

[ComVisible(true)]
[Guid("30BD35BE-D5CE-4751-A3B3-9D601F926E36")]
public abstract class OverlayIconBase : IShellIconOverlayIdentifier
{
    private const string OverlayIdentifiersKeyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers";
    private readonly string _iconFileName;
    protected OverlayIconBase()
    {
        _iconFileName = GetType().Assembly.Location;
    }

    protected static void Register(Type type, string registrationName)
    {
        string guid = type.GUID.ToString("B").ToUpper();

        string keyPath = OverlayIdentifiersKeyPath + "\\" + registrationName;
        using (var key = Registry.LocalMachine.CreateSubKey(keyPath))
        {
            key.SetValue(string.Empty, guid);
        }

        NativeMethods.SHChangeNotify(SHChangeNotifyEvents.AssocChanged, SHChangeNotifyFlags.IdList, IntPtr.Zero, IntPtr.Zero);
    }

    protected static void Unregister(Type type, string registrationName)
    {
        string keyPath = OverlayIdentifiersKeyPath + "\\" + registrationName;
        Registry.LocalMachine.DeleteSubKeyTree(keyPath, false);

        NativeMethods.SHChangeNotify(SHChangeNotifyEvents.AssocChanged, SHChangeNotifyFlags.IdList, IntPtr.Zero, IntPtr.Zero);
    }

    public int IsMemberOf(string path, uint attributes)
    {
        try
        {
            return ShouldDisplay(path) ? WinError.S_OK : WinError.S_FALSE;
        }
        catch
        {
            return WinError.E_FAIL;
        }
    }

    public int GetOverlayInfo(IntPtr pwszIconFile, int cchMax, out int iconIndex, out uint flags)
    {
        iconIndex = 0;
        flags = 0;
        if (string.IsNullOrEmpty(_iconFileName) || fileName.Length + 2 > cchMax)
            return WinError.E_FAIL;

        int count = Encoding.Unicode.GetByteCount(_iconFileName);
        byte[] bytes = new byte[count + 2];
        Encoding.Unicode.GetBytes(_iconFileName, 0, _iconFileName.Length, bytes, 0);
        Marshal.Copy(bytes, 0, pwszIconFile, bytes.Length);
        iconIndex = IconIndex;
        flags = (uint) (ShellIconOverlayIdentifierFlags.ISIOI_ICONFILE | ShellIconOverlayIdentifierFlags.ISIOI_ICONINDEX);
        return WinError.S_OK;
    }

    public int GetPriority(out int priority)
    {
        priority = Priority;
        return WinError.S_OK;
    }

    // 0-100 (0: highest); typically 0
    protected virtual int Priority { get { return 0; } }

    protected abstract bool ShouldDisplay(string path);
    protected abstract int IconIndex { get; }
}

[ComVisible(true)]
[Guid("76344480-04C1-4D15-A0A5-578881CEF415")]
public class MyOverlayIcon1 : OverlayIconBase
{
    private const string RegistrationName = "MyOverlayIcon1";

    [ComRegisterFunction]
    static void Register(Type t)
    {
        Register(t, RegistrationName);
    }

    [ComUnregisterFunction]
    static void Unregister(Type t)
    {
        Unregister(t, RegistrationName);
    }

    protected override bool ShouldDisplay(string path)
    {
        /* some logic to decide if the overlay should be displayed... */
    }

    protected override int IconIndex
    {
        get { return 0; }
    }
}

使用Win32Res将图标嵌入到DLL中,如here所述。

通过使用Debugger.Launch附加到explorer.exe,我能够确认GetOverlayInfoIsMemberOf按预期工作,但覆盖图不会显示在资源管理器中。

可能是什么问题?

1 个答案:

答案 0 :(得分:2)

您可能遇到与此主题中讨论的内容类似的问题。 Tortoise-svn icons not showing up under windows 7