我正在尝试为我的应用实现自定义叠加图标。这是(简化)代码:
[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,我能够确认GetOverlayInfo
和IsMemberOf
按预期工作,但覆盖图不会显示在资源管理器中。
可能是什么问题?