c# - AppDomain DoCallBack FileNotFound 异常

标签 c# appdomain filenotfoundexception

我将一个函数加载到新创建的 AppDomain 并且一切正常,但是如果我关闭程序然后重命名它并再次启动它,那么我将遇到 FileNotFound 异常。我只是不明白,怎么可能?

错误(appDomainProject原程序名)

System.IO.FileNotFoundException: Could not load file or assembly "appDomainProject, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null" or one of its dependencies. Can not find the file specified.

来源

using System;
using System.IO;
using System.Windows.Forms;

namespace appDomainProject
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            try
            {
                AppDomain authDomain = AppDomain.CreateDomain(DateTime.Now.ToString());
                authDomain.DoCallBack(load_Auth);
            }
            catch (Exception ex)
            {
                File.WriteAllText("e.txt", ex.ToString());;
                MessageBox.Show(ex.ToString());
            }
        }

        private static void load_Auth()
        {
            MessageBox.Show("AUTH");
        }
    }
}

最佳答案

我猜 exe 有一些关于它们的硬编码名称。事实上,如果您检查 typeof(Program).AssemblyName,它就是原始名称,这就是我认为我们会收到错误的原因。

但是,您始终可以手动将 dll 加载到 AppDomain 中,然后在其中放置一些类来拦截对“原始”名称的请求并将其替换为正确的程序集。

这段代码是这样做的:

/// <summary>
///  It seems that if you rename an exe and then try to load said 
///  assembly into a separate app-domain, .NET looks for the original
///  name.  This class loads the current assembly into the app
///  domain manually and then detects request for the original name 
///  and redirects it to the correct assembly.
/// 
///  http://stackoverflow.com/questions/37685180
/// </summary>
public class RenamedExeFixer : MarshalByRefObject
{
  /// <summary> Load the assembly that this type is in into the app-domain. </summary>
  public static void LoadOriginatingAssemblyIntoDomain(AppDomain appDomain)
  {
    var pathToSelf = new Uri(typeof(RenamedExeFixer).Assembly.CodeBase).LocalPath;
    appDomain.Load(File.ReadAllBytes(pathToSelf));

    // create an instance of the class inside of the domain
    // so that it can hook into the AssemblyResolve event
    appDomain.CreateInstanceFrom(pathToSelf, typeof(RenamedExeFixer).FullName);
  }

  private readonly string _myAssemblyName;

  public RenamedExeFixer()
  {
    // cached for efficiency (probably not needed)
    _myAssemblyName = typeof(RenamedExeFixer).Assembly.FullName;

    AppDomain.CurrentDomain.AssemblyResolve += HandleAssemblyResolve;
  }

  private Assembly HandleAssemblyResolve(object sender, ResolveEventArgs args)
  {
    if (args.Name == _myAssemblyName)
    {
      return typeof(RenamedExeFixer).Assembly;
    }

    return null;
  }
}

然后您需要做的就是在创建您的应用程序域后调用辅助方法:

AppDomain authDomain = AppDomain.CreateDomain(DateTime.Now.ToString());
RenamedExeFixer.LoadOriginatingAssemblyIntoDomain(authDomain);
authDomain.DoCallBack(load_Auth);

关于c# - AppDomain DoCallBack FileNotFound 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37685180/

相关文章:

C# 应用程序启动新修订删除所有内容

asp.net - 如何在 ASP .NET 中动态插入网页(并更新插件)?

asp.net - 每当重新加载应用程序域时,您如何强制 IIS 应用程序池重新启动?

使用 File 对象的 Java.io.FileNotFoundException

hadoop - 分布式缓存 Hadoop - FileNotFound

c# - 放置异步/等待的最佳做法是什么?

c# - 如何在 Visual Studio 中查看 Markdown 文本?

C# Visual Studio 单元测试,模拟客户端 IP 地址

c# - AppDomain.DynamicDirectory 未生成

java - 编译java程序filenotfound异常