Как использовать ведение журнала корпоративной библиотеки в настраиваемом действии .NET - PullRequest
5 голосов
/ 05 декабря 2008

У меня есть некоторый библиотечный код, который используется из моего приложения, а также используется настраиваемым действием .NET в проекте установщика Visual Studio. Код библиотеки, в свою очередь, использует блок ведения журнала Enterprise Library для ведения журнала. Как я могу получить информацию о конфигурации в Enterprise Library в контексте моего настраиваемого действия, выполняемого внутри msiexec? Можно ли загрузить механизм конфигурации в код перед тем, как я сделаю какие-либо вызовы EntLib?

Обновление: я создал хак, который, похоже, будет работать, но полагается на установку непубличного статического поля с помощью отражения. Обидно, что 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] вместе со сборкой пользовательского действия), а динамически загруженные сборки, вызванные в файле конфигурации, - нет. Обойти это невозможно.

Ответы [ 5 ]

1 голос
/ 03 марта 2009

Я полагаю, что проблема заключается в том, что ваша сборка настраиваемых действий загружается в LoadFrom контексте , поэтому ее манифестные зависимости разрешены относительно ее кодовой базы.

Вы можете решить эту проблему, создав новую AppDomain. Это даст вам возможность сбросить базовый каталог, загрузить новый файл App.config и т. Д. Используйте AppDomain.CreateDomain (String, Evidence, AppDomainSetup) для создания нового AppDomain, заполнив свойства AppDomainSetup для ApplicationBase, ConfigurationFile и т.

1 голос
/ 26 февраля 2009

Нет никакого способа использовать стандартный способ app.config, потому что этот app.config - это msiexec.config, который вам нужно отредактировать перед выполнением MSI. Я бы порекомендовал иметь свой собственный метод загрузки конфигурации, который читает из пользовательского XML или значений в MSI.

0 голосов
/ 27 февраля 2018

Это может помочь людям, которые все еще имеют дело с установщиками 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 о реализации обработчика .

0 голосов
/ 24 февраля 2009

У меня была похожая проблема с тем, что 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. Если вы сделаете это, вам нужно будет отредактировать MSI, используя что-то вроде Orca , чтобы заставить установщик установить в GAC до того, как он выполнит пользовательские действия, по умолчанию запускаются пользовательские действия.

Я все еще ищу действительно опрятное решение, и я обновлю этот ответ, когда найду его.

0 голосов
/ 12 декабря 2008

Не уверен, что это поможет, но вы можете записать в журнал 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

...