【问题标题】:MyAppDomain AssemblyResolve C#MyAppDomain AssemblyResolve C#
【发布时间】:2015-01-28 13:58:16
【问题描述】:

我有一个 DLL,我在需要自己处理外部程序集负载的环境中使用它。我想将程序集加载到 AppDomain 中。当我使用 CurrentAppDomain 尝试此操作时效果很好,但是在我自己创建的应用程序域中执行此操作时失败。 背景是我想在最后卸载appdomain,以便最终“释放”程序集。

public ZipEx() 
{
    try
    {
        AppDomainSetup domaininfo = new AppDomainSetup();
        domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
        Evidence adevidence = AppDomain.CurrentDomain.Evidence;

        //THIS CODE WORKS
        //System.AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        //System.AppDomain.CurrentDomain.Load("ICSharpCode.SharpZipLib");

        //THIS CODE DOES NOT WORK
        AppDomain zipDomain2 = AppDomain.CreateDomain("ADZib2", adevidence, domaininfo);
        PolicyLevel polLevel = PolicyLevel.CreateAppDomainLevel();
        PermissionSet permSet = new PermissionSet(PermissionState.Unrestricted);
        permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
        polLevel.RootCodeGroup.PolicyStatement = new PolicyStatement(permSet);
        zipDomain2.SetAppDomainPolicy(polLevel);
        zipDomain2.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show("ex in ctor" + Environment.NewLine + ex.ToString());
    }
    if (_loadedAssembly == null)
    {
    }
}

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    System.Windows.Forms.MessageBox.Show("CurrentDomain_AssemblyResolve");
    Assembly assembly = null;
    bool foundAssembly = false;

    int idx = args.Name.IndexOf(',');
    if (idx > 0)
    {
        string partialName = args.Name.Substring(0, idx);
        string dllName = partialName + ".dll";

        //Add the directorys where the assembly hould be resolved
        List<string> directorySearch = new List<string>
        {
          string.Format("{0}{1}{2}",Environment.CurrentDirectory,Path.DirectorySeparatorChar, dllName),
          string.Format("{0}{1}{2}",AppPath,Path.DirectorySeparatorChar, dllName)
        };

        foreach (string fileName in directorySearch)
        {
            if (File.Exists(fileName))
            {
                foundAssembly = true;
                assembly = Assembly.LoadFrom(fileName);
                break;
            }
        }

        if (assembly == null)
        {
            if (!foundAssembly)
            {
                foreach (string fileName in directorySearch)
                {
                }
            }
            else
            {
            }
        }
    }
    if (assembly != null) 
    {
        System.Windows.Forms.MessageBox.Show("assembly is not null");
    }
    return assembly;
}

我的问题是如何使用我创建的应用程序域来加载程序集?

【问题讨论】:

  • 当你说“不起作用”时,你是什么意思?没有事件、异常等?
  • 很难理解为什么您不使用 zipDomain2.AssemblyResolve 事件。或者不只是按照您喜欢的方式设置 AppDomainSetup。使用 Fuslogvw.exe 进行故障排除。
  • @Steve Mitcham 我的意思是它引发了一个没有找到程序集的异常。我的问题是它适用于 CurrentDomain
  • 正如@HansPassant 所说,fuslogvw.exe 将为您提供 CLR 用来尝试解决您的程序集的路径,因此您将能够找出它为什么找不到文件.
  • 好的,我会尝试的,但是为什么相同的 Resolve 方法对 CurrentDomain 有效?

标签: c# appdomain assembly-loading


【解决方案1】:

在您当前的示例中,我没有看到任何未注释的代码会导致新创建的 AppDomain 尝试加载程序集。我假设在此答案中未注释的代码中缺少对 Load 的调用。

根据AppDomain.Load 的帮助中的注释,它只能在当前的 AppDomain 中使用,否则它会尝试将程序集加载到 BOTH AppDomains 中,这可能是您遇到异常的原因。要将程序集仅加载到另一个 AppDomain,您应该调用其中一个 CreateInstance 函数。在这种特殊情况下,我推荐使用 CreateInstanceFromAndUnwrap 函数,因为它允许您按名称和类型指定程序集。

如果您没有想要实例化并且能够跨 AppDomain 边界进行交互的类型(这似乎不太可能但可能),您可能必须创建并丢弃一些简单的类型,如枚举或结构来获得它上班。

【讨论】:

  • 这与您没有太大关系,因为您的代码清楚地表明您正在加载一个 DLL,但对于其他停止此问题的人,也可以使用 AppDomain.ExecuteAssembly 运行可执行文件在另一个 AppDomain 中而不显式创建其任何类型。
  • 我会试一试。感谢您的提示,我会看看我能用它完成什么
  • 该死,我刚刚意识到别的事情。如果您上面的代码是您正在使用的代码并且即使没有调用 Load 也失败了,当您连接 AssemblyResolve 事件时,您也可能会收到此异常,因为新的 AppDomain 然后尝试加载原始 DLL 或 EXE (其中包含您的 CurrentDomain_AssemblyResolve 方法的那个)并且不能,因为它不在新 AppDomain 的 ApplicationBase 路径中。如果是这种情况,您可以尝试将原始可执行文件的副本放在您尝试从中加载的目录中,看看是否有帮助。
  • 我无法复制它,因为 inno setup 会将所有程序集复制到一个临时目录中,但并非全部都在同一个目录中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 2011-02-23
相关资源
最近更新 更多