VC++自定義加載DLL,從任意位置加載依賴(lài)的DLL
隱藏VS開(kāi)發(fā)的程序目錄下的DLL,可以將依賴(lài)的DLL放到指定位置去。
1.一直使用第三方控件,編譯后依賴(lài)的控件都在運(yùn)行目錄,或者system32目錄,看的很別扭,尋找過(guò)很多方法重定義加載,發(fā)現(xiàn)太復(fù)雜,最后無(wú)意間使用反射時(shí)發(fā)現(xiàn),同一個(gè)DLL放在不同的地方只會(huì)被加載一次,因?yàn)槊總€(gè)dll都有一個(gè)唯一的KEY,利用這個(gè)方法,人為的加載這些DLL,可以從任意位置加載,可以解決程序運(yùn)行目錄下一堆DLL文件的問(wèn)題。
這個(gè)方法只適用于反射方式加載的控件所依賴(lài)的DLL,不能對(duì)直接引用的DLL進(jìn)行預(yù)加載。
//初始化加載一些用到的DLL文件
try
{
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\DevComponents.DotNetBar2.dll"); //加載DLL
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\DevExpress.Data.v14.2.dll"); //加載DLL
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\DevExpress.Utils.v14.2.dll"); //加載DLL
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\DevExpress.XtraEditors.v14.2.dll"); //加載DLL
System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\IPAddressControlLib.dll"); //加載DLL
}
catch?(System::IO::FileNotFoundException^?e)
{
System::Windows::Forms::MessageBox::Show(e->Message,?"加載控件錯(cuò)誤,可能無(wú)法進(jìn)行配置!",
System::Windows::Forms::MessageBoxButtons::OK,?System::Windows::Forms::MessageBoxIcon::Error);
}2.對(duì)直接依賴(lài)以及引用的DLL進(jìn)行加載。
CLR會(huì)自動(dòng)從運(yùn)行目錄或system32加載DLL,如果沒(méi)有找到就會(huì)觸發(fā)?AssemblyResolve 事件,在此事件中就可以自己去加載需要的DLL文件,返回給CLR.
using?namespace?System::Reflection;
Assembly^?MyResolveEventHandler(Object^?sender,?ResolveEventArgs^?args); //申明
[STAThreadAttribute]
int?main(array^args)
{
AppDomain^?currentDomain?=?AppDomain::CurrentDomain;
//?在創(chuàng)建任何控件之前啟用?Windows?XP?可視化效果
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);?
currentDomain->AssemblyResolve?+=?gcnew?ResolveEventHandler(MyResolveEventHandler);
//?創(chuàng)建主窗口并運(yùn)行它
Application::Run(gcnew?Form1());
return?0;
}
//缺少DLL文件加載的事件
static?Assembly^?MyResolveEventHandler(Object^?sender,?ResolveEventArgs^?args)
{
String?^dll_name;
AssemblyName^?myAssemblyName?=
gcnew?AssemblyName(args->Name);
Console::WriteLine("Resolving..."?+?myAssemblyName->Name);
dll_name?=?myAssemblyName->Name;
if?(dll_name->IndexOf(".resources")?<?0) //一個(gè)DLL文件會(huì)產(chǎn)生2次事件,比如abc.dll??第一次是abc,需要自己添加DLL擴(kuò)展名,第二次會(huì)需要abc.resources,此時(shí)返回為空即可
{
dll_name?+=?".DLL";
}
else?return?nullptr; //resources返回為空即可
return?Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\"?+?dll_name);
}Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory()?+?"\DLL\"?+?dll_name);
這個(gè)就是從指定的位置加載DLL,可以更換為你自己定義的目錄或者從資源文件中加載。





