我可以使用C++/CLI实现shell命名空间扩展接口,但将实际工作传递给.NET?

我可以使用C++/CLI实现shell命名空间扩展接口,但将实际工作传递给.NET?,.net,c++-cli,com-interop,windows-shell,shell-extensions,.net,C++ Cli,Com Interop,Windows Shell,Shell Extensions,问我一些问题,但它(和答案)已经有两年多的历史了。我正在使用Visual Studio 2013和.NET 4.5[.1]。我还阅读了其他关注点,其中列出了与运行时回调包装器的交互,作为不使用.NET进行shell扩展的原因 我的想法是在C++中使用实际的shell接口作为本地C++类,但是把几乎所有的实际工作传递给.NET。这能解决MSDN文章中提到的许多问题(如RCW问题)吗 代码可能大致如下: namespace Managed { // C# public interface IS

问我一些问题,但它(和答案)已经有两年多的历史了。我正在使用Visual Studio 2013和.NET 4.5[.1]。我还阅读了其他关注点,其中列出了与运行时回调包装器的交互,作为不使用.NET进行shell扩展的原因

我的想法是在C++中使用实际的shell接口作为本地C++类,但是把几乎所有的实际工作传递给.NET。这能解决MSDN文章中提到的许多问题(如RCW问题)吗

代码可能大致如下:

namespace Managed { // C#
   public interface IShellFolder { … mimic native IShellFolder in C# … }
}

#include <shobjidl.h>
class CShellFolder : public IShellFolder // C++/CLI
{
   private: gcroot<Managed::IShellFolder> m_shellFolder;
};
名称空间管理{//C#
公共接口IShellFolder{…模仿C#…}中的本机IShellFolder
}
#包括
类CShellFolder:公共IShellFolder//C++/CLI
{
私有:gcroot m_shell文件夹;
};

Hmya,这些问题已经足够真实了,它看起来就像是微软在.NET程序员开始编写外壳扩展时收到的一个非常古老的支持调用样本。当然他们做到了,.NET让他们更容易上路。CLR很好地隐藏了许多讨厌的COM管道,以至于(几乎)完全看不见。这些问题不是.NET代码独有的,STA重入和接口封送在本机代码中也是一个很大的问题。只要你知道自己在做什么,就很容易避免。这在.NET中肯定是一个问题,您无法轻松找到它在做什么。这太容易了

他们甚至没有提到最大的问题,这是一个很大的暗示,这是旧的,CLR版本注入问题是一个很难解决的问题。首先,如果在.NET中还编写了另一个shell扩展,它将把CLR加载到资源管理器中。如果此扩展使用的版本比您所需的旧,那么您的扩展将无法加载,在尝试在甚至无法加载程序集的CLR上运行时将付诸东流。在CLR v4中已经做了一些工作来避免这种情况,但它并不完美,一个旧的版本在所有其他版本之前加载,仍然会导致失败

而且它不仅限于资源管理器,当您的shell扩展使用OpenFileDialog等常见的Windows功能时,它会被注入到任何进程中。编写一个可以注入任意进程而不会在该进程中造成麻烦的DLL是一件需要用非常强烈的希波克拉底誓言来处理的事情,尽管首先不会造成伤害。在整个CLR和抖动中拖动是一件非常不希腊化的事情

这类故障极难诊断,当Explorer无法加载您的扩展时,它不会给出提示。而因注入代码而死亡的程序永远不会提供任何可供查看的内容。你会接到一个客户的电话,他会告诉你“不行,帮帮我”。更糟糕的是,他会打电话给被你的分机终止的程序的所有者。这不是任何人都想接听的支持电话


和你一样,微软也不想接到支持电话,不得不向一个从未听说过的程序员解释这些COM细节。他们没有,官方不支持在.NET中编写shell扩展。你可以继续前进,忽略不祥的措辞,但如果你撞到了墙,你就不能向微软寻求帮助。不要指望来自任何一方的帮助,顺便说一句,shell扩展都是一个模糊的话题。

No;Reentrancy仍然是您链接到的页面中的一个问题:Reentrancy当CLR阻止单线程单元(STA)线程时,例如,由于Monitor.Enter、WaitHandle.WaitOne或竞争锁语句,CLR在其标准配置中会在等待时进入嵌套消息循环。许多扩展方法都被禁止处理消息,这种不可预测和意外的重入会导致异常行为,这很难重现和诊断。C++/CLI is.NET。您的C++/CLI代码将链接到CLR。唯一的方法是使用进程外通信(这正是explorer.exe对一些shell扩展所做的,比如预览处理程序-顺便说一句,其中允许使用.NET)。必须与价值20年的第三方shell扩展兼容的工作当然不是令人羡慕的。