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

时间:2014-02-03 20:43:27

标签: .net c++-cli com-interop windows-shell shell-extensions

Windows shell extension with C#Shell Namespace Extension. C#. C++, MFC, AT—what to use?询问我的一些问题,但它(和答案)已超过两年了。我正在使用Visual Studio 2013和.NET 4.5 [.1]。我还阅读了Guidance for Implementing In-Process Extensions,其中包括与Runtime Callback Wrapper的交互,以及不使用.NET进行shell扩展的原因。

我的想法是将C ++ / CLI中的实际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;
};

1 个答案:

答案 0 :(得分:4)

Hmya,这些问题是真实的,它看起来就像微软在.NET程序员开始编写shell扩展时得到的支持调用的一个非常古老的样本。当然,他们确实这样做了,.NET让它变得更容易很多。很多令人讨厌的COM管道被CLR很好地隐藏到它(几乎)完全不可见的程度。这些问题不是专用于.NET代码,STA重新入侵和接口编组在本机代码中也是一个非常大的问题。只要你知道自己在做什么,就很容易避免。这当然是.NET中的一个问题,你不能轻易找到它在做什么。它使太容易了。

他们甚至没有提到最大的问题,大提示这是旧的,CLR版本注入问题是一个非常难以解决的问题。首先,如果另一个 shell扩展也是用.NET编写的,它会将CLR加载到资源管理器中。如果此扩展程序使用的旧版本超出了您的要求,那么您的扩展程序将无法加载,因为尝试在无法加载程序集的CLR上运行时会崩溃。工作是在CLR v4中完成的,以避免这种情况,但它并不完美,一个旧的,在所有其他人仍然导致失败之前加载。

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

这种类型的故障非常难以诊断,资源管理器在无法加载您的分机时无法窥视。而那些死于注入代码的程序永远不会给任何东西看。您将接到客户的电话,他会告诉您,它不起作用,帮助我#34;。或者更糟糕的是,他会打电话给你的扩展程序杀死的程序的所有者。这不是任何人想要回答的那种支持电话。

就像你一样,微软也不想接受支持电话,并且必须向那些从未听说过它的程序员解释这些COM细节。而且他们没有,在.NET中编写shell扩展是正式不受支持的。你可以开拓进取,忽略不祥的措辞,但是如果你碰壁,那么就无法给微软打电话寻求帮助。无论如何,不​​要指望SO提供太多帮助,shell扩展是一个不起眼的主题。