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アイコンがWindows7の下に表示されない

于 2012-10-02T13:56:18.127 に答える