Как правильно установить теневое копирование для домена приложения по умолчанию

Относительно Могу ли я заставить AppDomain по умолчанию использовать теневые копии определенных сборок?, он описывает рабочее решение для активации теневого копирования в AppDomain по умолчанию для определенного каталога.

В основном это говорит об использовании этих простых методов:

AppDomain.CurrentDomain.SetShadowCopyPath(aDirectory);
AppDomain.CurrentDomain.SetShadowCopyFiles();

Но поскольку используемые здесь методы помечены как устаревшие, мне было интересно, какой сейчас правильный способ добиться того же. Предупреждение предупреждает:

Пожалуйста, исследуйте использование AppDomainSetup.ShadowCopyDirectories вместо

Домен приложения имеет член этого типа, называемый SetupInformation что может привести вас к этой простой реализации

AppDomain.CurrentDomain.SetupInformation.ShadowCopyDirectories = aDirectory;
AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";

К сожалению, это не имеет никакого эффекта. Итак, вопрос в том, есть ли способ изменить AppDomainSetup текущего домена приложения, чтобы активировать теневое копирование?

2 ответа

Решение

Насколько я знаю, эти методы работают только на.NET Framework версии 1.1. Для всех более поздних версий нельзя включить теневое копирование на главном домене приложений. Вам нужно создать новый AppDomain и настроить его соответствующим образом. Простой подход заключается в создании приложения-загрузчика, которое просто:

  • Создает новый домен приложений с включенным теневым копированием. Для этого вам нужно будет использовать одну из перегрузок AppDomain.CreateDomain, которые принимают параметр AppDomainSetup.
  • Выполняет ваше основное приложение, используя метод AppDomain.ExecuteAssembly.

Хорошую отправную точку можно найти в статье CodeProject по теневому копированию приложений. Следующая статья взята из статьи с небольшим изменением (путь кеша не указан:

using System;
using System.IO;

namespace Loader
{
    static class Program
    {
        [LoaderOptimization(LoaderOptimization.MultiDomainHost)]
        [STAThread]
        static void Main()
        {
            /* Enable shadow copying */

            // Get the startup path. Both assemblies (Loader and
            // MyApplication) reside in the same directory:
            string startupPath = Path.GetDirectoryName(
                System.Reflection.Assembly
                .GetExecutingAssembly().Location);

            string configFile = Path.Combine(
                startupPath,
                "MyApplication.exe.config");
            string assembly = Path.Combine(
                startupPath,
                "MyApplication.exe");

            // Create the setup for the new domain:
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationName = "MyApplication";
            setup.ShadowCopyFiles = "true"; // note: it isn't a bool
            setup.ConfigurationFile = configFile;

            // Create the application domain. The evidence of this
            // running assembly is used for the new domain:
            AppDomain domain = AppDomain.CreateDomain(
                "MyApplication",
                AppDomain.CurrentDomain.Evidence,
                setup);

            // Start MyApplication by executing the assembly:
            domain.ExecuteAssembly(assembly);

            // After the MyApplication has finished clean up:
            AppDomain.Unload(domain);
        }
    }
}

Тебе придется:

  • замещать MyApplication.exe с именем вашей исполняемой сборки.
  • замещать MyApplication с названием приложения.
  • замещать MyApplication.exe.config с именем файла конфигурации вашего приложения. Если у вас его нет, вам не нужно его устанавливать.

Вам не нужно создавать отдельное приложение. Вы можете просто создать поддомен в вашем методе main или вызвать метод main на основе AppDomain.CurrentDomain.IsDefaultAppDomain() значение:

public static void Main(string[] args)
{
    if (AppDomain.CurrentDomain.IsDefaultAppDomain())
    {
        // Loader
        var entryPoint = System.Reflection.Assembly
            .GetExecutingAssembly();

        var applicationName = entryPoint.GetName().Name;
        // Create the setup for the new domain:
        var setup = new AppDomainSetup();
        setup.ApplicationName = applicationName;
        setup.ShadowCopyFiles = "true"; // note: it isn't a bool

        // Create the application domain. The evidence of this
        // running assembly is used for the new domain:
        AppDomain domain = AppDomain.CreateDomain(
           applicationName,
            AppDomain.CurrentDomain.Evidence,
            setup);

        try
        {
            // Start MyApplication by executing the assembly:
            domain.ExecuteAssembly(entryPoint.Location, args);
        }
        finally
        {
            // After the MyApplication has finished clean up:
            AppDomain.Unload(domain);
        }
    }
    else
    {
        // Main
        ActualMain(args);
    }
}

public static int ActualMain(string[] args)
{
     //Hello-world!
}
Другие вопросы по тегам