大婶进,一个关于AppDomain.Load的问题

happyday1799 2014-02-11 04:10:32
有没有哪位大神在编码生涯中遇到过这样的一个问题:

byte[] bts = 来自网络的受保护的dll文件(不能保存在本地); //PS:此文件是正确的.NET dll文件
AppDomain domain = AppDomain.CreateDomain("NewDomain");
Assembly asm = domain.Load(bts); //PS:异常,系统找不到指定的文件。

调用AppDomain的Load(byte[] rawAssembly)方法就异常,有没有什么方法或者某个设置让AppDomain不依赖于文件呢?
...全文
992 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingruibin 2015-07-17
  • 打赏
  • 举报
回复
我也遇到了和你一的问题 从网络上加载dll时 需要先用assembly.load先加载一次 然后再使用appdomain.load来加载
happyday1799 2014-02-19
  • 打赏
  • 举报
回复
@fuapolloqi 用Assembly.Load(byte[])是没有问题的,但是用Appdomain的load就不行了
fuapolloqi 2014-02-19
  • 打赏
  • 举报
回复
引用 20 楼 happyday1799 的回复:
[quote=引用 19 楼 happyday1799 的回复:] [quote=引用 18 楼 fuapolloqi 的回复:] //建立应用程序域 AppDomainSetup ads = new AppDomainSetup(); ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;// System.Environment.CurrentDirectory; ads.DisallowBindingRedirects = false; ads.DisallowCodeDownload = true; ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; AppDomain ad = AppDomain.CreateDomain("tempDomain", null, ads); 然后用这个应用程序域加载程序集就可以实现你的 要求
噢,谢谢,那我先试试[/quote] 失败了,提示还是找不到文件;[/quote] 我这边是从数据库中找的DLL的byte[] 用这种方式完全没有问题 加载dll时用的Assembly.Load(dll)
happyday1799 2014-02-19
  • 打赏
  • 举报
回复
引用 19 楼 happyday1799 的回复:
[quote=引用 18 楼 fuapolloqi 的回复:] //建立应用程序域 AppDomainSetup ads = new AppDomainSetup(); ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;// System.Environment.CurrentDirectory; ads.DisallowBindingRedirects = false; ads.DisallowCodeDownload = true; ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; AppDomain ad = AppDomain.CreateDomain("tempDomain", null, ads); 然后用这个应用程序域加载程序集就可以实现你的 要求
噢,谢谢,那我先试试[/quote] 失败了,提示还是找不到文件;
happyday1799 2014-02-19
  • 打赏
  • 举报
回复
引用 18 楼 fuapolloqi 的回复:
//建立应用程序域 AppDomainSetup ads = new AppDomainSetup(); ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;// System.Environment.CurrentDirectory; ads.DisallowBindingRedirects = false; ads.DisallowCodeDownload = true; ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; AppDomain ad = AppDomain.CreateDomain("tempDomain", null, ads); 然后用这个应用程序域加载程序集就可以实现你的 要求
噢,谢谢,那我先试试
真相重于对错 2014-02-17
  • 打赏
  • 举报
回复
如果,上边不错,修改一下temp.dll存储形式,比如存入数据库等等,删除掉temp.dll,从数据库读取byte,装载,也就是修改一下loadfile函数,就能确定!
真相重于对错 2014-02-17
  • 打赏
  • 举报
回复
如果上边不错,再改一下去掉file.delete(strfilename),同时去掉EmitAssembly,看出不出错
真相重于对错 2014-02-17
  • 打赏
  • 举报
回复
static byte[] loadFile(string filename) { FileStream fs = new FileStream(filename, FileMode.Open); byte[] buffer = new byte[(int) fs.Length]; fs.Read(buffer, 0, buffer.Length); fs.Close(); File.Delete(filename)//试试这样出错吗? return buffer; }
happyday1799 2014-02-17
  • 打赏
  • 举报
回复
引用 10 楼 hdt 的回复:
还是说明你没有看明白那个例子,或者你缺乏基本的逻辑思维 那个例子只是通过反射发出生成一个程序集(temp.dll),然后把那个文件读出为byte数组,再通过assembly.load这个byte数组,装载 1,要确定是否要本地文件,你可以稍微修改一下代码比如读完为byte数组后delete那个文件,再assembly.load不就可以判断是否需要本地文件了吗? 如果需要,说明此路不通,另外想办法,如果不需要,你就要比较一下你的代码和例子的区别。 所以,msdn已经给了你提示,你还不明白怎么做,只能说明你没有弄明白那个例子,或者弄明白了那个例子,却缺乏逻辑思维。
好吧,大神,Assembly.Load byte[]是没错,有没有temp.dll文件都无所谓; 如果在Assembly装载dll以后再删除这个文件,然后在AppDomain中再装载这个Assembly是会异常的,这个你有试过吗? 没错,我确实没找到在AppDomain中找到如何不依赖文件的这个设置或者其他的什么方法,所以我才到CSDN上来找帮助,你提供了一个我已经在用的例子,并没有解决我问的问题,谢谢你提供的例子。
真相重于对错 2014-02-17
  • 打赏
  • 举报
回复
还是说明你没有看明白那个例子,或者你缺乏基本的逻辑思维 那个例子只是通过反射发出生成一个程序集(temp.dll),然后把那个文件读出为byte数组,再通过assembly.load这个byte数组,装载 1,要确定是否要本地文件,你可以稍微修改一下代码比如读完为byte数组后delete那个文件,再assembly.load不就可以判断是否需要本地文件了吗? 如果需要,说明此路不通,另外想办法,如果不需要,你就要比较一下你的代码和例子的区别。 所以,msdn已经给了你提示,你还不明白怎么做,只能说明你没有弄明白那个例子,或者弄明白了那个例子,却缺乏逻辑思维。
fuapolloqi 2014-02-17
  • 打赏
  • 举报
回复
//建立应用程序域 AppDomainSetup ads = new AppDomainSetup(); ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;// System.Environment.CurrentDirectory; ads.DisallowBindingRedirects = false; ads.DisallowCodeDownload = true; ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; AppDomain ad = AppDomain.CreateDomain("tempDomain", null, ads); 然后用这个应用程序域加载程序集就可以实现你的 要求
真相重于对错 2014-02-17
  • 打赏
  • 举报
回复
我做了实验,完全不需要本地文件,就可以实现你的要求
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;

class Test
{
	public static void Main()
	{
		AppDomain currentDomain = AppDomain.CurrentDomain;

		

		currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

		InstantiateMyType(currentDomain);   // OK!
	}

	static void InstantiateMyType(AppDomain domain)
	{
		try
		{
			// You must supply a valid fully qualified assembly name here.
			domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
		}
		catch (Exception e)
		{
			Console.WriteLine(e.Message);
		}
	}

	// Loads the content of a file to a byte array. 
	

	static Assembly MyResolver(object sender, ResolveEventArgs args)
	{
		AppDomain domain = (AppDomain)sender;

		// Once the files are generated, this call is
		// actually no longer necessary.
		//EmitAssembly(domain);
		String strdll = "dll 二进制据的base64代码";
		String strpdb = "符号表文件二进制数据base64代码";
		byte[] rawAssembly = System.Convert.FromBase64String(strdll);
		byte[] rawSymbolStore = System.Convert.FromBase64String(strpdb);
		Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);

		return assembly;
	}

	// Creates a dynamic assembly with symbol information
	// and saves them to temp.dll and temp.pdb
	static void EmitAssembly(AppDomain domain)
	{
		
	}
}
dll pdb文件 二进制的base64代码由于回帖字数限制,没发帖,你自己生成吧 用System.Convert.ToBase64String(byte流);
真相重于对错 2014-02-17
  • 打赏
  • 举报
回复
我这边生成dll后,读为byte流,再删除文件不出错!!!!
happyday1799 2014-02-17
  • 打赏
  • 举报
回复
引用 12 楼 hdt 的回复:
static byte[] loadFile(string filename) { FileStream fs = new FileStream(filename, FileMode.Open); byte[] buffer = new byte[(int) fs.Length]; fs.Read(buffer, 0, buffer.Length); fs.Close(); File.Delete(filename)//试试这样出错吗? return buffer; }
接下来会有错

byte[] rawAssembly = 来自网络,因为安全问题文件不在客户端;
if (rawAssembly == null ||
    rawAssembly.Length == 0)
    return null;
Assembly asm = Assembly.Load(rawAssembly); //正确
AppDomain domain = AppDomain.CreateDomain("new");
asm = domain.Load(asm.GetName()); //异常,因为没有这个文件;
happyday1799 2014-02-16
  • 打赏
  • 举报
回复
引用 8 楼 hdt 的回复:
[quote=引用 5 楼 happyday1799 的回复:] [quote=引用 3 楼 hdt 的回复:]
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;

class Test {
   public static void Main() {
      AppDomain currentDomain = AppDomain.CurrentDomain;

      InstantiateMyType(currentDomain);   // Failed!

      currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

      InstantiateMyType(currentDomain);   // OK!
   }

   static void InstantiateMyType(AppDomain domain) {
      try {
     // You must supply a valid fully qualified assembly name here.
         domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
      } catch (Exception e) {
         Console.WriteLine(e.Message);
      }
   }

   // Loads the content of a file to a byte array. 
   static byte[] loadFile(string filename) {
      FileStream fs = new FileStream(filename, FileMode.Open);
      byte[] buffer = new byte[(int) fs.Length];
      fs.Read(buffer, 0, buffer.Length);
      fs.Close();

      return buffer;
   }   

   static Assembly MyResolver(object sender, ResolveEventArgs args) {
      AppDomain domain = (AppDomain) sender;

      // Once the files are generated, this call is
      // actually no longer necessary.
      EmitAssembly(domain);

      byte[] rawAssembly = loadFile("temp.dll");
      byte[] rawSymbolStore = loadFile("temp.pdb");
      Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);

      return assembly;
   }

   // Creates a dynamic assembly with symbol information
   // and saves them to temp.dll and temp.pdb
   static void EmitAssembly(AppDomain domain) {
      AssemblyName assemblyName = new AssemblyName();
      assemblyName.Name = "MyAssembly";

      AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule", "temp.dll", true);
      TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public);

      ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
      ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
      ilGenerator.EmitWriteLine("MyType instantiated!");
      ilGenerator.Emit(OpCodes.Ret);

      typeBuilder.CreateType();

      assemblyBuilder.Save("temp.dll");
   }
}
哥们代码挺长,不过你的方法是把文件保存到本地,跑题了,还有你最后把dll保存到本地,完全可以这样 File.WriteAllBytes(path,bts);[/quote]
引用 5 楼 happyday1799 的回复:
[quote=引用 3 楼 hdt 的回复:]
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;

class Test {
   public static void Main() {
      AppDomain currentDomain = AppDomain.CurrentDomain;

      InstantiateMyType(currentDomain);   // Failed!

      currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

      InstantiateMyType(currentDomain);   // OK!
   }

   static void InstantiateMyType(AppDomain domain) {
      try {
     // You must supply a valid fully qualified assembly name here.
         domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
      } catch (Exception e) {
         Console.WriteLine(e.Message);
      }
   }

   // Loads the content of a file to a byte array. 
   static byte[] loadFile(string filename) {
   ...
}
哥们代码挺长,不过你的方法是把文件保存到本地,跑题了,还有你最后把dll保存到本地,完全可以这样 File.WriteAllBytes(path,bts);[/quote] 不是我跑题了,而是你没看懂我的代码,从byte流装入程序集,是.net提供的基本功能,我的例子是msdn,你把他搞清楚就应该明白了。 [/quote] 这个例子的代码我们平时就是这么用的,但对我说的问题没用,因为我的本地根本没有这个文件,而AppDomain是必须需要读取这个文件的程序集清单的,我想要的答案是能够不需要这个文件就可以在AppDomain中加载rawAssembly。
真相重于对错 2014-02-12
  • 打赏
  • 举报
回复
引用 5 楼 happyday1799 的回复:
[quote=引用 3 楼 hdt 的回复:]
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;

class Test {
   public static void Main() {
      AppDomain currentDomain = AppDomain.CurrentDomain;

      InstantiateMyType(currentDomain);   // Failed!

      currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

      InstantiateMyType(currentDomain);   // OK!
   }

   static void InstantiateMyType(AppDomain domain) {
      try {
     // You must supply a valid fully qualified assembly name here.
         domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
      } catch (Exception e) {
         Console.WriteLine(e.Message);
      }
   }

   // Loads the content of a file to a byte array. 
   static byte[] loadFile(string filename) {
      FileStream fs = new FileStream(filename, FileMode.Open);
      byte[] buffer = new byte[(int) fs.Length];
      fs.Read(buffer, 0, buffer.Length);
      fs.Close();

      return buffer;
   }   

   static Assembly MyResolver(object sender, ResolveEventArgs args) {
      AppDomain domain = (AppDomain) sender;

      // Once the files are generated, this call is
      // actually no longer necessary.
      EmitAssembly(domain);

      byte[] rawAssembly = loadFile("temp.dll");
      byte[] rawSymbolStore = loadFile("temp.pdb");
      Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);

      return assembly;
   }

   // Creates a dynamic assembly with symbol information
   // and saves them to temp.dll and temp.pdb
   static void EmitAssembly(AppDomain domain) {
      AssemblyName assemblyName = new AssemblyName();
      assemblyName.Name = "MyAssembly";

      AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule", "temp.dll", true);
      TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public);

      ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
      ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
      ilGenerator.EmitWriteLine("MyType instantiated!");
      ilGenerator.Emit(OpCodes.Ret);

      typeBuilder.CreateType();

      assemblyBuilder.Save("temp.dll");
   }
}
哥们代码挺长,不过你的方法是把文件保存到本地,跑题了,还有你最后把dll保存到本地,完全可以这样 File.WriteAllBytes(path,bts);[/quote]
引用 5 楼 happyday1799 的回复:
[quote=引用 3 楼 hdt 的回复:]
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;

class Test {
   public static void Main() {
      AppDomain currentDomain = AppDomain.CurrentDomain;

      InstantiateMyType(currentDomain);   // Failed!

      currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

      InstantiateMyType(currentDomain);   // OK!
   }

   static void InstantiateMyType(AppDomain domain) {
      try {
     // You must supply a valid fully qualified assembly name here.
         domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
      } catch (Exception e) {
         Console.WriteLine(e.Message);
      }
   }

   // Loads the content of a file to a byte array. 
   static byte[] loadFile(string filename) {
      FileStream fs = new FileStream(filename, FileMode.Open);
      byte[] buffer = new byte[(int) fs.Length];
      fs.Read(buffer, 0, buffer.Length);
      fs.Close();

      return buffer;
   }   

   static Assembly MyResolver(object sender, ResolveEventArgs args) {
      AppDomain domain = (AppDomain) sender;

      // Once the files are generated, this call is
      // actually no longer necessary.
      EmitAssembly(domain);

      byte[] rawAssembly = loadFile("temp.dll");
      byte[] rawSymbolStore = loadFile("temp.pdb");
      Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);

      return assembly;
   }

   // Creates a dynamic assembly with symbol information
   // and saves them to temp.dll and temp.pdb
   static void EmitAssembly(AppDomain domain) {
      AssemblyName assemblyName = new AssemblyName();
      assemblyName.Name = "MyAssembly";

      AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule", "temp.dll", true);
      TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public);

      ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
      ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
      ilGenerator.EmitWriteLine("MyType instantiated!");
      ilGenerator.Emit(OpCodes.Ret);

      typeBuilder.CreateType();

      assemblyBuilder.Save("temp.dll");
   }
}
哥们代码挺长,不过你的方法是把文件保存到本地,跑题了,还有你最后把dll保存到本地,完全可以这样 File.WriteAllBytes(path,bts);[/quote] 不是我跑题了,而是你没看懂我的代码,从byte流装入程序集,是.net提供的基本功能,我的例子是msdn,你把他搞清楚就应该明白了。
tcmakebest 2014-02-11
  • 打赏
  • 举报
回复
可能楼主的 dll 还要链接到其他的 dll 吧,而且要注意必须是 .net 中的 dll 文件,不是 C++ 那种。
happyday1799 2014-02-11
  • 打赏
  • 举报
回复
引用 4 楼 feiyun0112 的回复:
http://www.broes.nl/2012/09/assembly-load-and-filenotfoundexception/
他的问题文件是存在的,只是找不到而已,跟我的问题不一样,不过还是谢谢你。
happyday1799 2014-02-11
  • 打赏
  • 举报
回复
引用 3 楼 hdt 的回复:
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;

class Test {
   public static void Main() {
      AppDomain currentDomain = AppDomain.CurrentDomain;

      InstantiateMyType(currentDomain);   // Failed!

      currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

      InstantiateMyType(currentDomain);   // OK!
   }

   static void InstantiateMyType(AppDomain domain) {
      try {
     // You must supply a valid fully qualified assembly name here.
         domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
      } catch (Exception e) {
         Console.WriteLine(e.Message);
      }
   }

   // Loads the content of a file to a byte array. 
   static byte[] loadFile(string filename) {
      FileStream fs = new FileStream(filename, FileMode.Open);
      byte[] buffer = new byte[(int) fs.Length];
      fs.Read(buffer, 0, buffer.Length);
      fs.Close();

      return buffer;
   }   

   static Assembly MyResolver(object sender, ResolveEventArgs args) {
      AppDomain domain = (AppDomain) sender;

      // Once the files are generated, this call is
      // actually no longer necessary.
      EmitAssembly(domain);

      byte[] rawAssembly = loadFile("temp.dll");
      byte[] rawSymbolStore = loadFile("temp.pdb");
      Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);

      return assembly;
   }

   // Creates a dynamic assembly with symbol information
   // and saves them to temp.dll and temp.pdb
   static void EmitAssembly(AppDomain domain) {
      AssemblyName assemblyName = new AssemblyName();
      assemblyName.Name = "MyAssembly";

      AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule", "temp.dll", true);
      TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public);

      ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
      ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
      ilGenerator.EmitWriteLine("MyType instantiated!");
      ilGenerator.Emit(OpCodes.Ret);

      typeBuilder.CreateType();

      assemblyBuilder.Save("temp.dll");
   }
}
哥们代码挺长,不过你的方法是把文件保存到本地,跑题了,还有你最后把dll保存到本地,完全可以这样 File.WriteAllBytes(path,bts);
feiyun0112 2014-02-11
  • 打赏
  • 举报
回复
http://www.broes.nl/2012/09/assembly-load-and-filenotfoundexception/
加载更多回复(3)

111,093

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧