本文介绍了AppDomain 不制作影子文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道无法直接卸载加载的程序集,因此我创建了临时域并加载了程序集,但在创建影子文件时出错.

I understand loaded assembly can not be unloaded directly so I created temporary domain and loaded assembly but I got error in creating shadow files.

我写的代码如下:

[LoaderOptimization(LoaderOptimization.MultiDomainHost)]
[STAThread]
static void Main(string[] args)
{
    string startupPath = @"D:\Temp\MyLib\bin\Debug";
    string cachePath = Path.Combine(startupPath, "__cache");
    string assembly = Path.Combine(startupPath, "MyLib.dll");

    AppDomainSetup setup = new AppDomainSetup();
    setup.ApplicationName = "MyLIb";
    setup.ShadowCopyFiles = "true";
    setup.CachePath = cachePath;

    AppDomain domain = AppDomain.CreateDomain("MyLIb", AppDomain.CurrentDomain.Evidence, setup);

    var np = FindFileInPath("MyLib.dll", cachePath);
    var ass = Assembly.LoadFile(np);
    var types = ass.GetTypes();
    AppDomain.Unload(domain);
    }

我在路径中查找文件时出错找不到路径 'D:\Temp\MyLib\bin\Debug__cache' 的一部分."

I got error in finding file in path "could not find a part of the path 'D:\Temp\MyLib\bin\Debug__cache'."

public static string FindFileInPath(string filename, string path)
{
   filename = filename.ToLower();

   foreach (var fullFile in Directory.GetFiles(path))
   {
       var file = Path.GetFileName(fullFile).ToLower();
       if (file == filename)
           return fullFile;

   }
   foreach (var dir in Directory.GetDirectories(path))
   {
       var file = FindFileInPath(filename, dir);
       if (!string.IsNullOrEmpty(file))
                return file;
        }

        return null;
    }
  }

谁能帮我解决这个麻烦.

Could someone help me out of this trouble.

提前致谢.俊

推荐答案

要启动新的应用程序域,您需要设置 AppDomainSetup 的 ApplicationBase 属性.这是您要加载的 dll 的路径.此外,您需要设置 AppDomainSetup 对象的 ShadowCopyDirectories 属性.这将制作给定目录中所有 dll 的影子副本.CachePath 确定将在何处创建影子文件夹.

To start a new appdomain you need to set the ApplicationBase property of your AppDomainSetup. This is the path of the dll's you want to load. Also, you need to set the ShadowCopyDirectories property of your AppDomainSetup object. This will make a shadow copy of all the dll's that are in the given directories.The CachePath determines where the shadowfolders will be created.

有关详细信息,请参阅:AppDomainSetup 满足属性 ShadowCopyDirectories

For more information see: AppDomainSetup met property ShadowCopyDirectories

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = "MyLIb";
setup.ApplicationBase = dllsDir;
setup.ShadowCopyFiles = "true";
setup.CachePath = cachePath; 
setup.ShadowCopyDirectories = dllsDir; 
AppDomain = AppDomain.CreateDomain("MyAppDomain", null, setup);

您首先需要调用新应用程序域的 CreateInstanceAndUnwrap 方法.然后您就可以开始在新的 Appdomain 中加载 dll.

You first need to invoke the CreateInstanceAndUnwrap method of the new appdomain. Then you can begin loading dll's in the new Appdomain.

var proxy = AppDomain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), typeof(Proxy).FullName);
var assembly = proxy.GetAssembly(fullPathToDllInDllsDir);

这是您可以创建的代理"类.注意这个类最重要的部分是MarshalByRefObject

This is the "Proxy" class you can create. Note that the most important part of this class is the MarshalByRefObject

 public class Proxy : MarshalByRefObject
 {
        public Assembly GetAssembly(string assemblyPath)
        {
            try
            {
                return Assembly.Load(AssemblyName.GetAssemblyName(assemblyPath));
            }
            catch (Exception)
            {
                return null;
            }
        }   
} 

这将为该 dll 创建一个 shadowfolder 并将其加载到应用程序域中(如果 ShadowCopyFiles 设置为 true)

This will create a shadowfolder for that dll and load it in the appdomain (If ShadowCopyFiles is set to true)

额外:尽量使用Assembly.Load() 或Assembly.LoadFrom() 方法并尽量避免使用Assembly.LoadFile().这仅在非常特定的情况下才需要.请参阅此说明

Extra: Try to use the Assembly.Load() or Assembly.LoadFrom() methods and try to avoid the use of Assembly.LoadFile(). This is only needed in very specific cases. See this explanation

对于在没有上下文的情况下加载的程序集,问题可能是由于使用 Assembly.LoadFile 方法从不同路径加载相同的程序集而引起的.运行时会将从不同路径加载的两个程序集视为不同的程序集,即使它们的身份相同.

请注意,您可以使用 Assembly.LoadFrom 方法来加载这些程序集.因为它们现在位于探测路径中,所以它们将被加载到默认加载上下文而不是加载源上下文中.但是,我们建议您切换到 Assembly.Load 方法并提供完整的程序集显示名称,以确保始终使用正确的版本.

Note that you can use the Assembly.LoadFrom method to load these assemblies. Because they are now in the probing path, they will be loaded into the default load context instead of the load-from context. However, we recommend that you switch to the Assembly.Load method and supply full assembly display names to ensure that correct versions are always used.

这篇关于AppDomain 不制作影子文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-17 01:35