【问题标题】:What is the right way to set shadow copying for the default AppDomain为默认 AppDomain 设置卷影复制的正确方法是什么
【发布时间】:2012-09-20 13:26:44
【问题描述】:

关于Can I make the default AppDomain use shadow copies of certain assemblies?,它描述了一种在特定目录的默认 AppDomain 中激活卷影复制的工作解决方案。

基本上它说使用这些简单的方法:

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

但是因为这里使用的方法被标记为过时,所以我想知道现在完成相同操作的正确方法是什么。警告消息提示:

请调查 AppDomainSetup.ShadowCopyDirectories 的使用情况

AppDomain 有一个名为 SetupInformation 的此类成员,它可能会将您带到这种简单的实现方式

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

很遗憾,这没有任何效果。 那么问题来了,有没有办法改变当前appdomain的AppDomainSetup来激活shadow copy?

【问题讨论】:

  • 回答“不幸的是这没有效果。”(问了3年后,我知道),这是因为SetupInformation属性创建了一个克隆 的内部FusionStore 属性又是对用于初始化当前域的实际AppDomainSetup 的引用。这个想法是,在初始化之后,这些属性就不能再被修改了(尽管我想知道为什么他们没有让它们成为 gettor-only 来表示这一点)。

标签: .net appdomain shadow-copy appdomainsetup


【解决方案1】:

据我所知,这些方法仅适用于 .NET Framework 1.1 版。对于所有更高版本,您不能在主 AppDomain 上启用卷影复制。您需要创建一个新的AppDomain 并进行适当的设置。一个简单的方法是创建一个加载器应用程序:

可以在Shadow Copying of Applications 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 替换为应用程序配置文件的名称。如果您没有,则无需设置。

【讨论】:

  • 你可以为asp.net项目做这个。
【解决方案2】:

您无需创建单独的应用程序。您可以在主方法中生成子域或根据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!
}

【讨论】:

    猜你喜欢
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2023-03-11
    • 1970-01-01
    • 2020-08-04
    • 2013-09-06
    • 2017-12-17
    相关资源
    最近更新 更多