5

我有一些庫代碼可以從我的應用程序中使用,也可以在Visual Studio安裝程序項目中使用.NET自定義操作。庫代碼反過來使用企業庫日誌記錄塊來執行日誌記錄。我如何在msiexec內運行的自定義操作的上下文中將配置信息提供給企業庫?在我對EntLib進行任何調用之前,是否可以在代碼中引導配置機制?如何在.NET自定義操作中使用企業庫日誌記錄

更新:我製作了一個似乎可以工作的黑客,但依靠使用反射設置非公共靜態字段。很遺憾,EntLib與.NET ConfigurationManager緊密耦合。

var factory = new LogWriterFactory(new FakeConfigSource("foo.config")); 
var field = typeof (Logger).GetField("factory", BindingFlags.Static | BindingFlags.NonPublic); 
field.SetValue(null, factory); 
Logger.Write("Test"); 

更新2:雖然是黑客在試驗檯的工作原理,當MSIEXEC的上下文中運行,組裝裝載機沒有找到在配置文件中引用的組件。 Fuslogvw表示AppBase是windows system32目錄,這是有道理的。我不明白的是爲什麼找到自定義操作程序集的清單依賴關係(位於[TargetDir]目錄旁邊的自定義操作程序集),但在配置文件中調用的動態加載程序集卻沒有。看不到任何解決方法。

回答

0

不知道這是否有幫助,但可以從自定義操作中寫入msi日誌。 (示例VBScript如下:)

Const msiMessageTypeInfo = &H04000000 
Const msiMessageTypeFatalExit = &H00000000 
Const msiMessageTypeError = &H01000000 
Const msiMessageTypeWarning = &H02000000 
Const msiMessageTypeUser = &H03000000 

Dim rec : Set rec = Session.Installer.CreateRecord(1) 
rec.StringData(1) = "Your log message." 

Session.Message msiMessageTypeInfo, rec 

從MSDN更多信息:http://msdn.microsoft.com/en-us/library/aa371672.aspx

+0

是的,謝謝,但不是真的我以後。我正在使用使用企業庫的庫代碼。我實際上並不需要在任何地方登錄,只是使用entlib的深層嵌套代碼試圖從config初始化自己。 – jlew 2009-02-24 18:13:13

0

我曾與MSIEXEC不能夠加載自定義操作依賴類似的問題,目前我的解決辦法是複製的依賴程序集到系統目錄。這是一個糟糕的解決方案,但它確實有效。

string installDir = System.IO.Path.GetDirectoryName(
       System.Reflection.Assembly.GetExecutingAssembly().Location); 
System.IO.File.Copy(
       System.IO.Path.Combine(installDir, "<Insert Assembly Name>.dll"), 
       System.IO.Path.Combine(Environment.SystemDirectory, "<Insert Assembly Name>.dll"), 
       true); 

另一個選擇是將企業庫程序集安裝到GAC中。如果你這樣做,你需要使用類似Orca這樣的編輯msi來使安裝程序安裝到GAC中,然後運行默認的自定義操作。

我仍在尋找一個非常簡潔的解決方案,我會在找到它時更新此響應。

1

沒有辦法使用標準的app.config方式,因爲app.config是在執行MSI之前需要編輯的msiexec.config。我的建議是擁有自己的配置加載方法,該方法從定製XML或MSI中的值讀取。

+0

企業庫不可能出現。 – jlew 2009-02-26 20:50:19

0

這可能會幫助人們繼續處理VS安裝程序:可以使用自定義操作中動態加載的程序集,只需幫助運行時找到程序集。

您這樣做的方式是處理AppDomain.AssemblyResolve事件。我這樣做對我的安裝程序類的Install方法,像這樣:

internal class MyInstaller : Installer 
{ 
    public override void Install(IDictionary stateSaver) 
    { 
     base.Install(stateSaver); 

     AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
     { 
      // Resolve assemblies here, e.g.: 
      return 
       args.Name == "My.Assembly" 
       ? Assembly.LoadFrom(this.Context.Parameters["TARGETDIR"] + "\\My.Assembly.dll") 
       : null; 
     }; 

     // Continue install... 
    } 
} 

我會推薦閱讀MS Docs page on implementing the handler爲好。

相關問題