簡體   English   中英

將MEF與在Wix Toolset自定義操作中導入的泛型一起使用

[英]Use MEF with generics import inside Wix Toolset custom action

我有一些通用接口

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

及其在另一個.dll實現

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

然后我導入另一個班級

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

然后,我創建控制台應用程序,將帶有標記為[Export]類的.dll放入bin\\Debug文件夾中,然后運行

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

    Console.ReadLine();
}

一切正常,控制台顯示“ Gomo Sapiens”行。 但是,當我使用某些自定義操作創建Wix Installer時,該操作使用相同的MainEntry類並在InstallFinalize之后運行,因此導入不起作用:

<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 請注意,我的安裝程序最初將所有文件( .dll.exe )復制到Program Files(x86)\\SimpleLibrary ,然后使用MEF組合調用自定義操作。 我想強調的是,在調用的瞬間MainEntry構造所有.dlls就躺在里面Program Files夾和MEF看到他們,但無法找到要導入的內容。 問題只出現在泛型類型上,簡單的接口確實會導入。

.NET Framework版本為4.5C# 6.0 CustomAction.config

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

也嘗試過使用MefContrib ,情況是一樣的。

重要的是,安裝完成后,我從Program Files(x86)手動運行控制台應用Program Files(x86)一切正常。

因此,問題是如何從Wix's自定義操作中使用MEF ,如果不能,為什么?

我相當確定,在運行自定義操作時,安裝程​​序會將CA.dll二進制文件解壓縮到一個臨時目錄中,然后從那里運行它。 如果您在PATH中添加了任何內容,它將不會反映在安裝程序的環境中,因此您將不會檢測到任何新文件。

您可以通過運行msi日志(/ l * v log.txt)和/或同時捕獲procmon來進行驗證。

您可能需要將自相關的DLL打包在自解壓的CA.dll中。

您可以通過在自定義操作項目中定義<CustomActionContents>並將此MSBuild屬性的值設置為以-分隔的從屬DLL路徑列表來實現。 然后,在構建時,這些DLL與自定義操作dll一起將打包到CA.dll中,該CA.dll將被提取到一個臨時目錄中,以在運行時用於自定義操作。

實際上,我還有另一個答案,它提供有關CustomActionContents是什么以及它在這里做什么的更好的詳細信息。 它在注釋中說“以空格分隔”,但我已經證實它是;分隔。 如果您也想閱讀該代碼,這也將為您提供定義MSBuild目標和屬性的文件的位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM