2011-11-09 13 views
8

Strappare i capelli cercando di capire perché ho questo problema, quindi spero che qualcuno possa aiutare.MEF caricamento di plug-in da una cartella condivisa di rete

Ho un programma che utilizza MEF per caricare i plugin. Vorrei che la parte client e server del sistema fosse in grado di utilizzare lo stesso archivio di plug-in che si troverà sul server.

Il mio problema è che quando si imposta la posizione del plug-in su "C:\Users\Administrator\Desktop\ClientPlugins" il plug-in viene caricato correttamente. Se cambio la posizione in "\\XRP-SERVER\Users\Administrator\Desktop\ClientPlugins" il plug-in non viene caricato.

Quando inserisco "\\XRP-SERVER\Users\Administrator\Desktop\ClientPlugins" in Windows Explorer, la posizione viene trovata e la DLL del plugin è lì.

Per favore qualcuno potrebbe aiutarmi.

Fatemi sapere se avete bisogno di ulteriori informazioni.

Come da suggerimento ho provato la modifica della configurazione per includere quanto segue, ma questo non ha risolto i problemi ....

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

Cordiali saluti

Ash

risposta

2

Mi sono imbattuto in questo problema ieri e ho ridotto il problema a come MEF carica gli assiemi. Quando si crea un DirectoryCatalog, a sua volta crea una raccolta di AssemblyCatalogs. Ogni AssemblyCatalog fa un:

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

La chiamata a Assembly.Load genera un'eccezione sandbox (per un motivo che non so spiegare ancora) e, pertanto, nessuna parte si trovano in quanto cattura silenziosamente l'errore.

La cosa divertente è che chiamare Assembly.LoadFrom(<pathToYourDll>) per restituire un Assembly funziona correttamente (non viene generata alcuna eccezione). Combinalo con il costruttore sovraccarico di AssemblyCatalog che prende come input uno Assembly e tu hai una soluzione!

Quindi invece di utilizzare un DirectoryCatalog, elencho tutte le DLL nel percorso e creo iterativamente un AssemblyCatalog e lo aggiungo al mio CompositionContainer.

Nota: sto utilizzando il flag loadFromRemoteSources = "true" nel mio App.Config ed è obbligatorio, altrimenti si blocca sempre.

Spero che questo aiuti

+0

Im nel processo di provare questo e sono con te fino al punto in cui aggiungi AssemblyCatalog a CompositionContainer.Non vedo un metodo di add sulla CompositionContainer.Ci spiego un po 'di più per favore? – user589195

+0

Okay ho capito che devi creare un aggregatoCatalogo quindi aggiungi il tuo assemblyCataglogues e aggiungi il tuo aggregatoCatalogo a compositionContainer. – user589195

+0

Per favore fammi sapere se scopri perché questo funziona e il metodo standard non lo fa :) oso dire che Microsoft sarebbe interessata a sapere anche :) Grazie ancora per rispondi :) – user589195

0

Prova using System .IO.Path.PathSeparator invece di \?

Oppure è possibile recuperare prima il file nella posizione del client?

Non sono abbastanza sicuro di loro, ma vorrei provarlo.

+0

Grazie, proverò il separatore del percorso. Un compito futuro è lo streaming del plugin dal server tramite wcf se il client non ha accesso al percorso condiviso. Voglio che la posizione condivisa funzioni per prima cosa e voglio capire perché non lo è :) – user589195

+0

Un'altra cosa è, quando ci penso: usare "file: //"? – Anton

+0

Ho controllato che sto fornendo il percorso in formato che il C# può leggere. int fCount = Directory.GetFiles ("\\\\ XRP-SERVER \\ Users \\ Amministratore \\ Desktop \\ ClientPlugins", "*. *", SearchOption.TopDirectoryOnly) .Lunghezza; Console.WriteLine (fCount); Restituisce 1 che è la dll di plugin – user589195

8

Le politiche di sicurezza in genere disabilitano il caricamento del codice remoto (ovvero, gli assembly su una posizione esterna).

si può provare la seguente modifica di configurazione:

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

L'altra cosa da considerare è quando si copiano i file di ritorno da percorsi di rete, che in genere hanno una zona specificata nella loro flusso di dati alternativo. In explorer, questo può essere rimosso usando il comando "Unblock" quando si visualizzano le proprietà di un file.

In alternativa, è possibile rimuovere la Zona dal flusso di dati alternativo, come mostrato in here on Mike Hadlow's blog.

+0

Quando l'ho visto, i miei occhi si sono illuminati mentre pensavo che avrebbe funzionato. Non sembra averlo fatto però :(Ho inserito questo nella configurazione e non verrà ancora caricato quando si utilizza il percorso "\\ XRP-SERVER \ Users \ Administrator \ Desktop \ ClientPlugins". Altre idee? – user589195

2

Giusto per chiarire la risposta di sebd funziona.

Ecco il codice finale che ho usato.

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