1

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

[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 中,如此处所述

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

可能是什么问题呢?

4

1 回答 1

2

您可能遇到了与此线程中讨论的类似的问题。Tortoise-svn 图标在 Windows 7 下不显示

于 2012-10-02T13:56:18.127 回答