简体   繁体   English

MEF从网络共享文件夹加载插件

[英]MEF loading plugins from a network shared folder

Tearing my hair out trying to work out why Im having this problem so hope someone can help. 撕裂我的头发试图弄清楚为什么我有这个问题,所以希望有人可以提供帮助。

I have a program that uses MEF to load plugins. 我有一个使用MEF加载插件的程序。 I would like the client and server part of the system to be able to use the same plugin store that will be located on the server. 我希望系统的客户端和服务器部分能够使用将位于服务器上的相同插件存储。

My problem is that when I set the plugin location to " C:\\Users\\Administrator\\Desktop\\ClientPlugins " the plugin is loaded fine. 我的问题是,当我将插件位置设置为“ C:\\Users\\Administrator\\Desktop\\ClientPlugins ”时,插件被正确加载。 If I change the location to " \\\\XRP-SERVER\\Users\\Administrator\\Desktop\\ClientPlugins " the plugin is not loaded. 如果我将位置更改为“ \\\\XRP-SERVER\\Users\\Administrator\\Desktop\\ClientPlugins ”,则不会加载插件。

When I enter " \\\\XRP-SERVER\\Users\\Administrator\\Desktop\\ClientPlugins " into windows explorer the location is found and the plugin dll is there. 当我在Windows资源\\\\XRP-SERVER\\Users\\Administrator\\Desktop\\ClientPlugins输入“ \\\\XRP-SERVER\\Users\\Administrator\\Desktop\\ClientPlugins ”时,找到位置并且插件dll在那里。

Please could someone help. 请有人帮忙。

Let me know if you require anymore information. 如果您需要更多信息,请与我们联系。

As per a suggestion I have tried editing the config to include the following but this has not fixed the issues.... 根据一个建议我已经尝试编辑配置包括以下但这没有解决问题....

  <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <runtime>
        <loadFromRemoteSources enabled="true"/>
      </runtime>

Kind Regards 亲切的问候

Ash

Security policies will typically disable loading remote code (that being, assemblies on an external location). 安全策略通常会禁用加载远程代码(即外部位置的程序集)。

You can try the following config change: 您可以尝试以下配置更改:

<runtime>
    <loadFromRemoteSources enabled="true"/>
</runtime>

The other thing to be aware of is when you are copying files back from network locations, they will typically have a Zone specified in their alternate data stream. 另一件需要注意的事情是,当您从网络位置复制文件时,它们通常会在其备用数据流中指定区域。 In explorer, this can be removed by using the "Unblock" command when viewing the properties of a file. 在资源管理器中,可以在查看文件属性时使用“取消阻止”命令将其删除。

Alternatively, you could programatically remove the Zone from the alternate data stream, as shown here on Mike Hadlow's blog . 或者,您可以以编程方式从备用数据流中删除区域,如Mike Hadlow的博客中所示

I ran into this problem yesterday and narrowed the problem down to how MEF loads assemblies. 我昨天遇到了这个问题,并将问题缩小到MEF加载程序集的方式。 When you create a DirectoryCatalog, it in turns creates a collection of AssemblyCatalogs. 创建DirectoryCatalog时,它会创建一个AssemblyCatalog集合。 Each AssemblyCatalog does an: 每个AssemblyCatalog都执行以下操作:

    AssemblyName assemblyName = AssemblyName.GetAssembly();
    Assembly.Load(assemblyName);

The call to Assembly.Load throws a sandbox Exception (for a reason I can't explain yet) and therefore no parts are found since it silently catches the error. Assembly.Load的调用抛出了一个沙箱异常(由于我无法解释的原因),因此没有找到任何部分,因为它无声地捕获错误。

The funny thing is that calling Assembly.LoadFrom(<pathToYourDll>) to return an Assembly works fine (no exception is thrown). 有趣的是调用Assembly.LoadFrom(<pathToYourDll>)来返回一个Assembly集正常工作(没有抛出异常)。 Combine that with the overloaded constructor of AssemblyCatalog that takes an Assembly as its input and you got yourself a workaround! 将它与AssemblyCatalog的重载构造函数相结合,它将Assembly作为输入,你得到了一个解决方法!

So instead of using a DirectoryCatalog , I list all the DLLs in the path and iteratively create an AssemblyCatalog and add it to my CompositionContainer . 因此,我没有使用DirectoryCatalog ,而是列出路径中的所有DLL,并迭代地创建AssemblyCatalog并将其添加到CompositionContainer

Note : I am using the loadFromRemoteSources="true" flag in my App.Config and it is required, otherwise it always crashes. 注意:我在App.Config中使用loadFromRemoteSources =“true”标志并且它是必需的,否则它总是崩溃。

Hope this helps 希望这可以帮助

Just to clarify sebd's answer works. 只是为了澄清sebd的回答是有效的。

Heres the final code I used. 这是我使用的最终代码。

string[] files = Directory.GetFiles(ClientPluginStore, "*.dll", SearchOption.TopDirectoryOnly);

AggregateCatalog aggCat = new AggregateCatalog();

aggCat.Catalogs.Add(catalog);

foreach ( string file in files )
{
    Assembly ass = Assembly.LoadFrom(file);

    AssemblyCatalog assCat = new AssemblyCatalog(ass);

    aggCat.Catalogs.Add(assCat);
}

_container = new CompositionContainer(aggCat);

Try using System.IO.Path.PathSeparator instead of \\? 尝试使用System.IO.Path.PathSeparator而不是\\?

Or may be fetch the file to client location first? 或者可能首先将文件提取到客户端位置?

I'm not pretty sure about them, but I would give it a try. 我不太确定他们,但我会尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM