2017-12-13 7 views
0

の内側にインポート私はその後、私は別のクラスに使用MEFは、ウィックスツールセットカスタムアクション

namespace SimpleLibrary 
{ 
    public class MainEntry 
    { 
     [Import] 
     public IImported<string> Imported { get; set; } 

     public MainEntry() 
     { 
      try 
      { 
       var catalog = new DirectoryCatalog(Dir); 
       var container = new CompositionContainer(catalog); 
       container.ComposeParts(this); 

       Imported.Value = "Gomo Sapiens"; 
      } 
      catch (CompositionException ex) 
      { 
       System.Diagnostics.Debugger.Launch(); 
      } 
      catch (Exception ex) 
      { 
       System.Diagnostics.Debugger.Launch(); 
      } 
     } 

     private string Dir 
     { 
      get 
      { 
       var dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "SimpleLibrary"); 

       if (!Directory.Exists(dir)) 
       { 
        dir = AppDomain.CurrentDomain.BaseDirectory; 
       } 

       return dir; 
      } 
     } 
    } 
} 
をインポートを行い、いくつかの一般的なインタフェース別 .dll

namespace ImportedLibrary 
{ 
    [Export(typeof(IImported<>))] 
    public class ExportedEntry<T> : IImported<T> 
    { 
     public T Value { get; set; } 
    } 
} 

namespace SimpleLibrary 
{ 
    public interface IImported<T> 
    { 
     T Value { get; set; } 
    } 
} 

とその実装を持っています

次に、コンソールアプリケーションを作成し、.dllをクラスm bin\Debugフォルダ内[Export]をarkedと

static void Main(string[] args) 
{ 
    MainEntry me = new MainEntry(); 
    Console.WriteLine(me.Imported.Value); 

    Console.ReadLine(); 
} 

すべては、コンソールが表示ライン "GoMoについてサピエンス" 正常に動作し実行します。 しかし、私は同じMainEntryクラスを使用してInstallFinalize後に実行されるいくつかのカスタムアクションでWixはインストーラを作成するときに、インポートが動作しません:

<Binary Id="ServerActions" SourceFile="path to CA.dll" /> 

<CustomAction Id="RunMainEntry" BinaryKey="ServerActions" DllEntry="RunMainEntry" Execute="immediate" Return="check" /> 

<InstallExecuteSequence> 
    <Custom Action='RunMainEntry' After='InstallFinalize'>NOT Installed AND NOT WIX_UPGRADE_DETECTED</Custom> 
</InstallExecuteSequence> 

とカスタムアクションコード

public class CustomActions 
{ 
    [CustomAction] 
    public static ActionResult RunMainEntry(Session session) 
    { 
     MainEntry me = new MainEntry(); 
     session.Log(me.Imported.Value); 

     return ActionResult.Success; 
    } 
} 

カスタムアクションはスローCompositionException。私のインストーラは、最初にProgram Files(x86)\SimpleLibraryの中にすべてのファイル(.dll.exe)をコピーしてから、MEFのカスタムアクションを呼び出します。私はMainEntryコンストラクタを呼び出す瞬間に.dllsProgram Filesフォルダ内にあり、MEFはそれを見るがインポートするものは見つからないことを強調したい。問題はジェネリック型だけで現れ、シンプルなインターフェイスはインポートを行います。

.NET Frameworkバージョンは4.5,C# 6.0です。 CustomAction.config

<configuration> 
    <startup useLegacyV2RuntimeActivationPolicy="true">   
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
</configuration> 

はまたMefContribを使用しようとした、状況は同じです。

重要なことは、インストール後にコンソールアプリケーションを手動でProgram Files(x86)から実行すると、すべて正常に動作することです。

どうすればいいですか?MEFWix'sカスタムアクションからどうすればいいですか?

答えて

0

私は、カスタムアクションを実行すると、インストーラはCA.dllバイナリを一時ディレクトリに展開し、そこから実行することがかなり確信しています。 PATHに何かを追加した場合は、インストーラの環境に反映されないため、新しいファイルを検出しません。

msi logging(/ l * v log.txt)を実行して確認したり、procmonで実行して同時にキャプチャすることもできます。

おそらく、自己解凍型CA.dll自体に依存DLLをパッケージする必要があります。

カスタムアクションプロジェクトに<CustomActionContents>を定義し、このMSBuildプロパティの値を独立したDLLへのパスの分離リストに設定することでこれを行うことができます。次に、ビルド時に、これらのDLLとカスタムアクションDLLがCAにパッケージされます。dllは実行時にカスタムアクションのために一時ディレクトリに展開されます。

実際には、CustomActionContentsの詳細と、それが何であるかについての詳細について、別の回答があります。hereコメントに「スペース区切り」と書かれていますが、私はそれを確認しました。これは、MSBuildのターゲットとプロパティが定義されているファイルの場所も指定します。

+0

私は '.dll'を' [Export] 'と一緒にカスタムアクションproject、no luckの参照に含めることをお勧めしました。私の例で見てきたように、 'Main Entry'クラスをアセンブリの実行場所から作成するのではなく、' Program Files'フォルダから検索します。実行時に '.dll'が存在することが分かります。だから大失敗が予想された – ivanblin

+0

うまく動作するはずです。手動でファイルを配置して動作させることができるからです。 procmonでファイルデータをキャプチャして、ロードしようとしているものと探しているものを確認します。たぶんそれはこれについていくつかの光を当てることができます。 –

+0

私はprocmonの動作を正確に理解していませんが、インストーラーが '.dll'を探している場所を監視する機能があれば、デバッグモードで実行できます – ivanblin

関連する問題