AppDomain DoCallBack FileNotFound异常

时间:2016-06-07 17:00:34

标签: c# appdomain filenotfoundexception

我将一个函数加载到新创建的AppDomain并且所有工作都很好,但是如果我关闭程序然后重命名并再次启动它,那么我将有FileNotFound异常。我只是不明白,怎么会这样?

错误(appDomainProject原始程序名称)

var process = new sys.io.Process('powershell', ['any parameters']);

来源

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.

2 个答案:

答案 0 :(得分:2)

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

但是,你总是可以手动将dll加载到AppDomain中,然后在那里有一些类来截取" orginal"的请求。命名并用正确的程序集替换它。

此代码执行此操作:

/// <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;
  }
}

然后您需要做的就是在创建app-domain后调用helper方法:

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

答案 1 :(得分:0)

抱歉,这是设计......

作为一种解决方法,您可以将方法移动到外部dll,这样就可以重命名.exe。

如果您希望应用程序只有一个文件,可以使用ILmerge