AppDomain加载与释放dll - kevin-Y - 博客园
来源:百度文库 编辑:神马文学网 时间:2024/04/29 06:53:44
我与很多人都在找这问题的答案。还好,我很幸运,没有进入很多人都进入的死胡同而漫长的讨论中。因为我找到了这篇文章
黄天不负有心人,终于全身而退,哈哈
文章说得很明白,我去掉其他设置,只使用以下代码时
AppDomain.CurrentDomain.SetShadowCopyFiles();
在文章发布的几天后,我在微软的MSDN上发现了这文章。似乎阐述得更为系统
http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharp05162002.mspx
在加载dll时有一个奇怪现象,以下代码会报错 object objBuild = pJobDomain.CreateInstanceAndUnwrap(strDllFilePath,strClassName);说没找到dll或依赖的项,看报错提示的路径却是实实在在有这个dll的。
于是使用以下代码System.Reflection.Assembly asm = pJobDomain.Load(str[1]);
object objBuild = asm.CreateInstance(str[0]);
if(objBuild==null)
Mag.Windows.Interface.Log.AddErr("buildWorker","创建对象失败");
else
iDo = (Mag.Windows.Interface.IDo)objBuild;Unload后是可以重新编译dll的。
上面的代码还有一个问题,就是我UnLoad程序域后,重新编译dll,也看到dll成功更新了。应用程序域检测到配置被修改后,重新使用上面的代码载入dll,但程序结果并不是我期待的!!程序行为还是上面版本dll的。估计是使用了缓存的dll。尝试换用以下代码System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath,strClassName);
object objBuild = objHandle.Unwrap();问题解决。汗,我以为上面的代码可以用CreateInstanceAndUnwrap来代替。
设置SetShadowCopyFiles后,程序运行期间,程序文件是可以随意更新的,不过不会应用这些变化,除非重新启动程序。不过在我的项目中这个不是问题。因为主程序是极小去更新的,但相关的dll就需要不断的修正,并重新加载到程序域中。所以上文的提示已很足够了。以下是我的代码//创建 AppDomainSetup 对象
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.ShadowCopyDirectories = "true";
//主程序很少更新,可以不设置,但考虑还要有可能,
//设置后,更新完文件直接通知网管重启就可以了。不需要先关再上传文件,再通知开启这么麻烦
AppDomain.CurrentDomain.SetShadowCopyFiles();
//新域的 config 和本域公用一个。不使用默认的配置文件。
// setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
//安全级别相同
System.Security.Policy.Evidence adevidence = AppDomain.CurrentDomain.Evidence;
//创建新的辅程序域
this.domainJob = AppDomain.CreateDomain("Mag.Web.MainSrv.Jobs",adevidence,setup);
//辅程序域,dll都加载在这,更新频繁,这是一定要设置的。
this.domainJob.SetShadowCopyFiles();
加载dllprivate Mag.Windows.Interface.IDo buildWorker(System.AppDomain pJobDomain,string config)
{
string [] str = config.Split(',');
string strDllFilePath = string.Format("{0}{1}.dll",AppDomain.CurrentDomain.BaseDirectory,str[1]);
string strClassName = str[0];
if(!System.IO.File.Exists(strDllFilePath))
{
//throw new Exception("指定的文件不存在");
Mag.Windows.Interface.Log.AddErr("buildWorker","指定的文件不存在" + strDllFilePath);
return null;
}
Mag.Windows.Interface.IDo iDo=null;
try
{
//使用当前程序域加载
// System.Runtime.Remoting.ObjectHandle objHandle = Activator.CreateComInstanceFrom(strDllFilePath,strClassName);
// object objBuild = objHandle.Unwrap();//建立对像
System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath,strClassName);
object objBuild = objHandle.Unwrap();
//会引起找到不dll或依赖的项的错误。
// object objBuild = pJobDomain.CreateInstanceAndUnwrap(strDllFilePath,strClassName);
//会首先使用缓存中的dll
// System.Reflection.Assembly asm = pJobDomain.Load(str[1]);
// object objBuild = asm.CreateInstance(str[0]);
if(objBuild==null)
Mag.Windows.Interface.Log.AddErr("buildWorker","创建对象失败");
else
iDo = (Mag.Windows.Interface.IDo)objBuild;
}
catch(Exception ee)
{
// throw ee;
Mag.Windows.Interface.Log.AddErr("buildWorker",ee);
}
return iDo;
}
黄天不负有心人,终于全身而退,哈哈
文章说得很明白,我去掉其他设置,只使用以下代码时
AppDomain.CurrentDomain.SetShadowCopyFiles();
在文章发布的几天后,我在微软的MSDN上发现了这文章。似乎阐述得更为系统
http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharp05162002.mspx
在加载dll时有一个奇怪现象,以下代码会报错 object objBuild = pJobDomain.CreateInstanceAndUnwrap(strDllFilePath,strClassName);说没找到dll或依赖的项,看报错提示的路径却是实实在在有这个dll的。
于是使用以下代码System.Reflection.Assembly asm = pJobDomain.Load(str[1]);
object objBuild = asm.CreateInstance(str[0]);
if(objBuild==null)
Mag.Windows.Interface.Log.AddErr("buildWorker","创建对象失败");
else
iDo = (Mag.Windows.Interface.IDo)objBuild;Unload后是可以重新编译dll的。
上面的代码还有一个问题,就是我UnLoad程序域后,重新编译dll,也看到dll成功更新了。应用程序域检测到配置被修改后,重新使用上面的代码载入dll,但程序结果并不是我期待的!!程序行为还是上面版本dll的。估计是使用了缓存的dll。尝试换用以下代码System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath,strClassName);
object objBuild = objHandle.Unwrap();问题解决。汗,我以为上面的代码可以用CreateInstanceAndUnwrap来代替。
设置SetShadowCopyFiles后,程序运行期间,程序文件是可以随意更新的,不过不会应用这些变化,除非重新启动程序。不过在我的项目中这个不是问题。因为主程序是极小去更新的,但相关的dll就需要不断的修正,并重新加载到程序域中。所以上文的提示已很足够了。以下是我的代码//创建 AppDomainSetup 对象
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.ShadowCopyDirectories = "true";
//主程序很少更新,可以不设置,但考虑还要有可能,
//设置后,更新完文件直接通知网管重启就可以了。不需要先关再上传文件,再通知开启这么麻烦
AppDomain.CurrentDomain.SetShadowCopyFiles();
//新域的 config 和本域公用一个。不使用默认的配置文件。
// setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
//安全级别相同
System.Security.Policy.Evidence adevidence = AppDomain.CurrentDomain.Evidence;
//创建新的辅程序域
this.domainJob = AppDomain.CreateDomain("Mag.Web.MainSrv.Jobs",adevidence,setup);
//辅程序域,dll都加载在这,更新频繁,这是一定要设置的。
this.domainJob.SetShadowCopyFiles();
加载dllprivate Mag.Windows.Interface.IDo buildWorker(System.AppDomain pJobDomain,string config)
{
string [] str = config.Split(',');
string strDllFilePath = string.Format("{0}{1}.dll",AppDomain.CurrentDomain.BaseDirectory,str[1]);
string strClassName = str[0];
if(!System.IO.File.Exists(strDllFilePath))
{
//throw new Exception("指定的文件不存在");
Mag.Windows.Interface.Log.AddErr("buildWorker","指定的文件不存在" + strDllFilePath);
return null;
}
Mag.Windows.Interface.IDo iDo=null;
try
{
//使用当前程序域加载
// System.Runtime.Remoting.ObjectHandle objHandle = Activator.CreateComInstanceFrom(strDllFilePath,strClassName);
// object objBuild = objHandle.Unwrap();//建立对像
System.Runtime.Remoting.ObjectHandle objHandle = pJobDomain.CreateInstanceFrom(strDllFilePath,strClassName);
object objBuild = objHandle.Unwrap();
//会引起找到不dll或依赖的项的错误。
// object objBuild = pJobDomain.CreateInstanceAndUnwrap(strDllFilePath,strClassName);
//会首先使用缓存中的dll
// System.Reflection.Assembly asm = pJobDomain.Load(str[1]);
// object objBuild = asm.CreateInstance(str[0]);
if(objBuild==null)
Mag.Windows.Interface.Log.AddErr("buildWorker","创建对象失败");
else
iDo = (Mag.Windows.Interface.IDo)objBuild;
}
catch(Exception ee)
{
// throw ee;
Mag.Windows.Interface.Log.AddErr("buildWorker",ee);
}
return iDo;
}
AppDomain加载与释放dll - kevin-Y - 博客园
彻底告别加载dll出错
汇编总结 - Kevin Wan‘s Doodle - 博客园
汇编总结 - Kevin Wan‘s Doodle - 博客园
加载XX.dll时出错的一般解决方法
彻底告别dll出错 开机加载项大揭秘
在VC++中创建DLL文件并加载
在VC++中创建DLL文件并加载
理解AppDomain
DEF与Dll构建
中文分词免费发布ChineseTokenizer.dll - Eunge - 博客园
如何在C#中加载自己编写的动态链接库(DLL)
动态加载Silverlight应用的dll文件(可实现插件功能) - 代震军BLOG - ...
开机时出现加载w7x2.dll出错 - 电脑维修网
如何在C#中加载自己编写的动态链接库(DLL) - liweihua200204的专栏
WINDOWS无法启动,提示加载内核所需的DLL文件,联系技术人员
如何在C#中加载自己编写的动态链接库(DLL)
风度与气质 Y
Matlab画图操作 - Kevin的日志 - 网易博客
Word论文排版技巧 - kevin的日志 - 网易博客
DLL
C#程序调用非托管C++ DLL文件的方法 - Chase的技术博客 - 博客园
博客园 - Bear.sTaR{R} - 保护你的DLL和Code不被别人使用。
[C#/C ]C#调用非托管DLL的APIs - .NET人字拖 - 博客园