为什么用Assembly.LoadFrom能读取的程序集,不能用AppDomain.Load来读取。

黄土豆 2003-08-19 09:10:15
同一个dll,用Assembly.LoadFrom可以正确读取使用,但用AppDomain.Load方法却不能读取,错误提示为:反序列化信息不足,需要详细信息。

在这个Dll的类中,我按照MSDN的帮助文件为类作了序列化标记。

[Serializable] public class Const
{
......
}

期待能尽快得到解答。
...全文
235 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
LevinForum 2003-08-20
  • 打赏
  • 举报
回复
其实创建了一个AppDomain后,一般是直接调用CreateInstanceFromAndUnwrap的。..~~~~
再不是你把Assembly安装到GAC里试试..
LevinForum 2003-08-20
  • 打赏
  • 举报
回复
Activator.CreateInstance是静态的。在当前域创建.

AppDomain domain=....后,
domain也是一个MarshalByRefObject,它是属于它自己的域的.
但是你要控制该域,在该域上开始一条线程来执行你的代码,
你可以去参考AppDomain.DoCallBack的例子

如果是使用CreateInstanceFromAndUnwrap,那么就更加简单了。
你只需要定义一个小小的Assembly,里面做个类似这样的类:
public class DomainController : MarshalByRefObject
{
public void RunSync(string assemblyLocation)
{
//加载你想使用AppDomian.Load的程序集
Assembly asm=Assembly.LoadFrom(assemblyLocation);
//取得目标类型
Type t=asm.GetType("目标类型");
//运行该类型上的静态方法
t.GetMethod("Run",BindingFlags.Static|BindingFlags.Public).Invoke(null,null);
}
}
--------------------
那样你在原AppDomain中这样调用:

object domainctrl=domain.CreateInstanceFromAndUnwrap(tempfileOfDomainController,"DomainController");
domainctrl.GetType().InvokeMember("RunSync",BindingFlags.Public|BindingFlags.Instance|BindingFlags.InvokeMethod,null,domainctrl,new object[]{filename});

---------------
事实上,IE也有个类似的小类,叫做IEHost,就是用来嵌入到新建的域,然后负责加载网页上指定的Assembly的。

黄土豆 2003-08-20
  • 打赏
  • 举报
回复
我也用过CreateInstanceFromAndUnwrap,但对于它的用法无法理解。它返回了一个System.MarshalByRefObject对象。而我应该如何使用这个对象呢?

我参考了http://www.microsoft.com/china/msdn/library/dncscol/html/csharp05162002.asp
《AppDomain和动态加载》一文,下载了它的源码。它这样使用Appdomain

remoteLoader = (RemoteLoader) appDomain.CreateInstanceFromAndUnwrap("SuperGraph.exe", "SuperGraphInterface.RemoteLoader");

RemoteLoader是在当前应用程序中定义的一个派生于MarshalByRefObject类,给我的感觉好象是appDomain先加载当前应用程序中的一个类型,然后再在这个类里调用Assembly。这种做法很古怪,让我难以理解。

Msdn中关于CreateInstanceAndUnwrap的示例是先创建一个动态程序集,在创建的时候得到这个程序集的Type,然后把CreateInstanceAndUnwrap返回的对象,当作InvokeMember的参数来使用,这和Activator.CreateInstance好象没什么区别,而我要加载磁盘上已经存在的程序集应该到哪里得到这个Type呢?

我对CreateInstanceAndUnwrap有许多困惑,所以难以运用,能不能简单的介绍一下它的用法,或者推荐一篇关于它的文章(中文的最好,英文的也行),不甚感激。
黄土豆 2003-08-19
  • 打赏
  • 举报
回复
AppDomain是通过传入一个目录位置来创建的。创建代码如下。

AppDomainSetup appsetup=new AppDomainSetup();
appsetup.ApplicationBase=v_CodeBase;//v_CodeBase是传入的目录位置。
appsetup.PrivateBinPath=AppDomain.CurrentDomain.BaseDirectory;
appsetup.ApplicationName="CommonComponent";
appsetup.ShadowCopyFiles="true";
appsetup.ShadowCopyDirectories=v_CodeBase;
appsetup.LoaderOptimization=LoaderOptimization.MultiDomain;

appdomain=AppDomain.CreateDomain("CommonComponent",null,appsetup);
黄土豆 2003-08-19
  • 打赏
  • 举报
回复
多谢思远,但我现在不能用Assembly的Load、LoadFrom及LoadFile,必须使用appdomain,因为我必须能够卸载它。

AppDomain.Load() is only meant to be called on AppDomain.CurrentDomain. (It's meant for interop callers only. They need a non-static method, and Assembly.Load() is static.) If you call it on a different AppDomain, if the assembly successfully loads in the target appdomain, remoting will then try to load it in the calling appdomain, potentially causing a FileNotFoundException/SerializationException for you.

我想我的问题就出在这里吧,但是我并没有成功地把一个程序集读入到一个appdomain,事实上,在第一次读取时就出现了这个问题。难道appdomain在创建时就会自动加载BaseDirectory
目录下的所有程序集吗?

另外,出现了这个问题应该如何解决呢?不好意思,我的英文不好,看这些资料很费力。谁能直接的告诉我一下解决的办法吗?
LevinForum 2003-08-19
  • 打赏
  • 举报
回复
AppDomain是谁建的?
目标AppDomain的dotnet版本一致?
黄土豆 2003-08-19
  • 打赏
  • 举报
回复
AssemblyList tasel=new AssemblyList();
tasel.Ase=appdomain.Load(astr);
tasel.TypeList=tasel.Ase.GetTypes();
tasel.TObjs=new Hashtable();

//===============================================

[SerializationException: 反序列化对象的状态不足。需要详细信息。]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +264
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +877
System.AppDomain.Load(String assemblyString) +0
ASP.UserProj.set_CurrentModule(String value) in J:\HomePage\MyWebNet\fmt\Common.cs:91
ASP.Common.GetConnectionString() in J:\HomePage\MyWebNet\fmt\Common.cs:353
ASP.Common.get_ConnectionString() in J:\HomePage\MyWebNet\fmt\Common.cs:280
ASP.MyTest2_aspx.Page_Load(Object sender, EventArgs e) in J:\HomePage\MyWebNet\fmt\MyTest2.aspx:22
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +731


LevinForum 2003-08-19
  • 打赏
  • 举报
回复
出错的StackTrace?
黄土豆 2003-08-19
  • 打赏
  • 举报
回复
我知道是显示名,如果是文件名的话,错误就是:找不到程序集文件或文件的依赖项。

LevinForum 2003-08-19
  • 打赏
  • 举报
回复
...
AppDomain.Load的参数是Assembly的DisplayName,而不是Location.
saucer 2003-08-19
  • 打赏
  • 举报
回复
see
Choosing a Binding Context
http://blogs.gotdotnet.com/suzcook/CategoryView.aspx/Loader

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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