2016-09-07 16 views
1

私はMEFを使用して自分のWPFアプリケーション用の "プラグイン"を作成しています。これらのプラグインの中には、EXEファイルを直接スタンドアローンにする必要があるものがあります。私は他のすべての参考資料と共にリソースを埋め込むためにFod​​yのCosturaを使用しています。 exeファイルをスタンドアロンにする必要があるため、これらのプラグインのディレクトリを作成してDirectoyCatalogを使用することはできませんMEF - 埋め込みDLLからアセンブリを取得

埋め込みリソースからアセンブリを読み込むこともできますし、単にアセンブリ名を指定することもできます:

catalog.Catalogs.Add(new AssemblyCatalog("My.Assembly.Name)); 

私はマニフェストリソースをループしようとしているが、これらはFodyでzip形式で圧縮されるように表示されます。

var resourceNames = GetType().Assembly.GetManifestResourceNames(); 
      foreach (var resourceName in resourceNames) 

感謝すべてのヘルプ/提案。あなたは、単に任意のCosturaジップを見つける抽出関数を呼び出し、それを使用するには

答えて

2

[OK]をので、以下のクラス(https://github.com/Sebazzz/EntityProfiler/blob/master/src/UI/EntityProfiler.Viewer/AppBootstrapper.csでこのコードを発見し、自分のニーズに合わせて微調整)を使用して、これは私のために働くようになりましたリソースマニフェストのファイルを解凍して解凍して登録します。

この関数は、関数で渡された文字列と一致するすべてのアセンブリの辞書を返します。私は、それらを反復し、組成物容器が使用するカタログに追加します。

var assemblies = CosturaAssemblyExtractor.Extract(AppDomain.CurrentDomain, Assembly.GetExecutingAssembly(), "My.AssemblyName"); 
foreach (var assembly in assemblies) 
{ 
    catalog.Catalogs.Add(new AssemblyCatalog(assembly.Value)); 
} 
container = new CompositionContainer(catalog); 

クラス:

public static class CosturaAssemblyExtractor 
{ 
    public static Dictionary<string, Assembly> Extract(AppDomain OrigDomain, Assembly ExecutingAssembly, string AssemblyStartsWith) 
    { 
     //var currentDomain = origDomain; 
     var assemblies = OrigDomain.GetAssemblies(); 

     var references = new Dictionary<string, Assembly>(); 

     var manifestResourceNames = ExecutingAssembly.GetManifestResourceNames().Where(x => { 
      return x.ToUpper().StartsWith(("costura." + AssemblyStartsWith).ToUpper()) && x.ToUpper().EndsWith(".dll.zip".ToUpper()); 
     }); 

     foreach (var resourceName in manifestResourceNames) 
     { 
      var solved = false; 
      foreach (var assembly in assemblies) 
      { 
       var refName = string.Format("costura.{0}.dll.zip", GetDllName(assembly, true)); 
       if (resourceName.Equals(refName, StringComparison.OrdinalIgnoreCase)) 
       { 
        references[assembly.FullName] = assembly; 
        solved = true; 
        break; 
       } 
      } 

      if (solved) 
       continue; 

      using (var resourceStream = ExecutingAssembly.GetManifestResourceStream(resourceName)) 
      { 
       if (resourceStream == null) continue; 

       if (resourceName.EndsWith(".dll.zip")) 
       { 
        using (var compressStream = new DeflateStream(resourceStream, CompressionMode.Decompress)) 
        { 
         var memStream = new MemoryStream(); 
         CopyTo(compressStream, memStream); 
         memStream.Position = 0; 

         var rawAssembly = new byte[memStream.Length]; 
         memStream.Read(rawAssembly, 0, rawAssembly.Length); 
         var reference = Assembly.Load(rawAssembly); 
         references[reference.FullName] = reference; 
        } 
       } 
       else 
       { 
        var rawAssembly = new byte[resourceStream.Length]; 
        resourceStream.Read(rawAssembly, 0, rawAssembly.Length); 
        var reference = Assembly.Load(rawAssembly); 
        references[reference.FullName] = reference; 
       } 
      } 
     } 
     return references; 
    } 

    private static void CopyTo(Stream source, Stream destination) 
    { 
     var array = new byte[81920]; 
     int count; 
     while ((count = source.Read(array, 0, array.Length)) != 0) 
     { 
      destination.Write(array, 0, count); 
     } 
    } 

    private static string GetDllName(Assembly assembly, bool withoutExtension = false) 
    { 
     var assemblyPath = assembly.CodeBase; 
     return withoutExtension ? Path.GetFileNameWithoutExtension(assemblyPath) : Path.GetFileName(assemblyPath); 
    } 
} 
関連する問題