user589195
user589195

Reputation: 4240

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. 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. If I change the location to "\\XRP-SERVER\Users\Administrator\Desktop\ClientPlugins" the plugin is not loaded.

When I enter "\\XRP-SERVER\Users\Administrator\Desktop\ClientPlugins" into windows explorer the location is found and the plugin dll is there.

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

Upvotes: 11

Views: 2739

Answers (4)

user589195
user589195

Reputation: 4240

Just to clarify sebd's answer works.

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);

Upvotes: 3

sebd
sebd

Reputation: 612

I ran into this problem yesterday and narrowed the problem down to how MEF loads assemblies. When you create a DirectoryCatalog, it in turns creates a collection of AssemblyCatalogs. Each AssemblyCatalog does an:

    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.

The funny thing is that calling Assembly.LoadFrom(<pathToYourDll>) to return an Assembly works fine (no exception is thrown). Combine that with the overloaded constructor of AssemblyCatalog that takes an Assembly as its input and you got yourself a workaround!

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.

Note : I am using the loadFromRemoteSources="true" flag in my App.Config and it is required, otherwise it always crashes.

Hope this helps

Upvotes: 4

Matthew Abbott
Matthew Abbott

Reputation: 61599

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.

Upvotes: 8

Anton
Anton

Reputation: 1419

Try using System.IO.Path.PathSeparator instead of \?

Or may be fetch the file to client location first?

I'm not pretty sure about them, but I would give it a try.

Upvotes: 0

Related Questions