假设您正在开发一个名为"ThirdParty.dll"
的第三方DLL,它有一个名为JustTryToInstantiateMe
的类。假设您的客户有一个引用"ThirdParty.dll"
的EXE,或者EXE没有"ThirdParty.dll"
的引用,但是如果以某种方式请求,EXE可以在PATH中找到"ThirdParty.dll"
。您无法控制EXE,因为您是"Thirdparty.dll"
的供应商,并且您只能修改DLL的功能。您的客户,即编写EXE的客户,同意引用您的DLL或将您的DLL放入PATH。没什么。
有没有办法在运行EXE时实例化JustTryToInstantiateMe
而不显式使用new
或调用静态/共享方法/字段/属性?
也许只是以某种方式使用静态/共享构造函数?也许在AssemblyLoad()
事件?也许使用注册表?一个启动过程?寻找想法......
答案 0 :(得分:1)
我知道如何执行此操作的最近方法是动态加载程序集,然后从您创建的类的实例调用方法。
以下是代码中c#的模板:
//add using for system.reflection
String className = "[NAME OF CLASS WITH FULL NAMESPACE GOES HERE]";
String methodName = "[METHOD NAME GOES HERE]"
String dllPath = "[FILE PATH FOR DLL GOES HERE]";
Assembly assembly = Assembly.LoadFile(dllPath);
Type type = assembly.GetType(className);
MethodInfo method = type.GetMethod(methodName);
object context = Activator.CreateInstance(type);
//optionally set up parameters here
object[] parameters = new object[0];
String result = (String) method.Invoke(context, parameters);
例如,我可以像这样创建一个类(我知道,它是VB,但接下来是C#。
Public Class my_class
Private hello = "hello world"
Public Function gethello()
Return hello
End Function
End Class
然后在编译之后,我可以在C#中使用以下代码来做我认为你在问的问题:
//using system.reflection
String className = "mytestlibrary.my_class";
String dllPath = "...mytestlibrary.dll";
String methodName = "gethello";
Assembly assembly = Assembly.LoadFile(dllPath);
Type type = assembly.GetType(className);
MethodInfo method = type.GetMethod(methodName);
object context = Activator.CreateInstance(type);
object[] parameters = new object[0];
String result = (String) method.Invoke(context, parameters);
//result is "hello world"
现在,如果你想做同样的事情,但是已经编译好的EXE文件,那么代码几乎没有什么不同,但你需要创建一个桌面/控制台应用程序来封装其他可执行文件并正确命名你的DLL。因此,在您的应用程序中,添加以下代码以从EXE中引用的DLL中获取类的实例。
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
String className = "My_Class";
String ExePath = "[PATH TO EXE]";
String methodName = "gethello";
Assembly assembly = Assembly.LoadFile(ExePath);
Type type = assembly.GetType(className);
MethodInfo method = type.GetMethod(methodName);
object context = Activator.CreateInstance(type);
object[] parameters = new object[0];
String result = (String) method.Invoke(context, parameters);
你也可以动态地将程序集加载到EXE中,但这有点棘手,所以我现在暂时将其保留在此处,除非你真的需要动态地将你的DLL加载到EXE中。
答案 1 :(得分:0)
从研究中我发现这个问题的简单答案是这是不可能的。简短的回答是,为了加载DLL中的类,需要通过某些东西引用类。如果一个DLL能够通过JUST在PATH中自我加载,这将带来各种安全问题。