我目前正在创建一个命名空间扩展。所以我想在计算机中创建一个条目,并让 explorer.exe 调用我的 IShellFolder 实现。我让它工作了几分钟(我愚蠢地决定在提交之前清理代码),所以我就在附近。
但我注意到一些非常奇怪的事情:更改 Class 的 GUID 值会改变我在 explorer.exe 中看到的内容
我发现那个问题告诉我我没有做坏事
这是代码:
装配信息.cs:
[assembly: ComVisible(false)]
[assembly: Guid("007C5100-4251-47BE-8141-D2AD3F496E6A")]
根文件夹.cs:
[ClassInterface(ClassInterfaceType.None)
[Guid("007C5101-4251-47BE-8141-D2AD3F496E6A"), ComVisible(true)]
public class RootFolder : IShellFolder, IShellFolder2, IPersistFolder, IPersistFolder2 {
private const String _mountPoint = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace\\{0}";
private const String _mountName = "CLSID\\{0}";
#region Shell Extension Registration
[ComRegisterFunction()]
public static void Register(Type t)
{
Console.WriteLine("Registering {0}...", t.GUID);
try {
if (t.GUID == null)
throw new ArgumentException("CLSID must not be null");
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(String.Format(_mountPoint, t.GUID.ToString("B")))) {
key.SetValue(null, "RootFolder");
}
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(String.Format(_mountName, t.GUID.ToString("B")), true)) {
key.SetValue(null, "RootFolder");
using (RegistryKey shFolder = key.CreateSubKey("ShellFolder")) {
shFolder.SetValue("Attributes", 0x78000040);
shFolder.SetValue("WantsFORPARSING", "");
}
}
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved")) {
key.SetValue(t.GUID.ToString("B"), "RootFolder");
}
IntPtr pidl = NativeMethod.SHGetKnownFolderIDList(KnownFolder.ComputerFolder.clsid, 0, IntPtr.Zero);
NativeMethod.SHChangeNotify(NativeMethod.FSNotification.UpdateDir, NativeMethod.ItemMeaning.IDList, pidl, IntPtr.Zero);
} catch (Exception ex) {
Logger.Write(Logger.Severity.Fatal, "Registration error: {0}", ex.Message);
throw; // Re-throw the exception
}
}
[ComUnregisterFunction()]
public static void Unregister(Type t)
{
try {
if (t.GUID == null)
throw new ArgumentException("CLSID must not be null");
Registry.CurrentUser.DeleteSubKey(String.Format(_mountPoint, t.GUID.ToString("B")), false);
using (RegistryKey k = Registry.ClassesRoot.OpenSubKey(String.Format(_mountName, t.GUID.ToString("B")), true)) {
if (k != null)
k.DeleteSubKey("ShellFolder");
}
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved")) {
if (key != null)
key.DeleteValue(t.GUID.ToString("B"), false);
}
IntPtr pidl = NativeMethod.SHGetKnownFolderIDList(KnownFolder.ComputerFolder.clsid, 0, IntPtr.Zero);
NativeMethod.SHChangeNotify(NativeMethod.FSNotification.UpdateDir, NativeMethod.ItemMeaning.IDList, pidl, IntPtr.Zero);
} catch (Exception ex) {
Logger.Write(Logger.Severity.Critical, "Registration error: {0}", ex.Message);
throw; // Re-throw the exception
}
}
#endregion
#region IShellFolder2 Inheritance
[All the methods looks like that, this is just a test]
public IEnumIDList EnumObjects(IntPtr hwndOwner, EnumObject flags)
{
Logger.Write("Tracing....");
throw new NotImplementedException();
}
#endregion
#region IPersistFolder2 Inheritance
[Ditto]
#endregion
}
我的 GUID 使用范围 007C5{100...120}-4251-47BE-8141-D2AD3F496E6A 当我的扩展程序的 GUID 为 007C5101 时,它只显示没有任何属性的“RootFolder”。当它有 007C5100(与程序集相同)或 007C5102 或 007C5103 时,它显示为“系统文件夹”(即使它不调用我的 DLL)。我对这种行为有点困惑,改变 GUID 怎么会导致这种变化?
注意:我在注册表中搜索了 4251-47BE-8141-D2AD3F496E6A(我的 GUID 的不可变部分),但在取消注册后找不到任何内容。