5

我有一些从我的应用程序中使用的库代码,也被 Visual Studio 安装程序项目中的 .NET 自定义操作使用。库代码反过来使用企业库日志记录块来进行日志记录。如何在 msiexec 中运行的自定义操作的上下文中将配置信息获取到企业库?在我对 EntLib 进行任何调用之前,是否可以在代码中引导配置机制?

更新:我制作了一个看起来可以工作但依赖于使用反射设置非公共静态字段的hack。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:虽然该 hack 在测试平台中有效,但在 msiexec 的上下文中运行时,程序集加载器找不到配置文件中引用的程序集。fuslogvw表示AppBase是windows system32目录,这有点意思。我不明白为什么会找到自定义操作程序集的清单依赖项(位于自定义操作程序集旁边的 [TargetDir] 目录中),但在配置文件中调用的动态加载程序集却没有。看不到任何解决方法。

4

5 回答 5

1

无法使用标准的 app.config 方式,因为 app.config 是您在执行 MSI 之前需要编辑的 msiexec.config。我的建议是使用您自己的配置加载方法,该方法从自定义 XML 或 MSI 中的值读取。

于 2009-02-26T12:05:31.387 回答
1

我认为问题在于您的自定义操作程序集正在加载中LoadFromcontext,因此其清单依赖关系相对于其代码库已解决。

您可以通过创建一个新的AppDomain. 这将使您有机会重置基本目录、加载新App.config文件等。使用AppDomain.CreateDomain(String, Evidence, AppDomainSetup)创建新的 AppDomain,为 ApplicationBase、ConfigurationFile 等填充AppDomainSetup 属性。

于 2009-03-03T00:13:24.020 回答
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 中,默认情况下自定义操作首先运行。

我仍在寻找一个非常巧妙的解决方案,当我找到它时我会更新这个响应。

于 2009-02-24T15:23:15.373 回答
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

于 2008-12-12T06:17:35.713 回答
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 页面

于 2018-02-26T21:01:07.913 回答