C# 引用.net dll+;非托管dll 我有一个项目(称为平台)引用.NETDLL(调用IT工具代理),使用dLimPART(调用IT工具)引用C++ DLL。仪器及其代理始终是同一版本,并且始终作为一个版本部署
我需要能够在一台机器上部署多个仪器(及其代理),并且只有一个平台使用特定版本的仪器C# 引用.net dll+;非托管dll 我有一个项目(称为平台)引用.NETDLL(调用IT工具代理),使用dLimPART(调用IT工具)引用C++ DLL。仪器及其代理始终是同一版本,并且始终作为一个版本部署,c#,.net,dllimport,C#,.net,Dllimport,我需要能够在一台机器上部署多个仪器(及其代理),并且只有一个平台使用特定版本的仪器 我好像不能给GAC设置一个代理,因为它使用C++ DLL。我可以将一个工具(及其代理)安装到特定的文件夹中,但如何确保平台能够找到该dll Upd. 理论上我希望看到的想法是,在正常开发时引用此dll,但能够让我的应用程序在自定义文件夹中搜索此dll 您可以将非托管dll文件复制到一个文件夹,然后将该文件夹添加到系统路径变量,也可以将这些文件复制到Windows\System32,因为该文件夹始终位于系统路径中
我好像不能给GAC设置一个代理,因为它使用C++ DLL。我可以将一个工具(及其代理)安装到特定的文件夹中,但如何确保平台能够找到该dll
Upd.理论上我希望看到的想法是,在正常开发时引用此dll,但能够让我的应用程序在自定义文件夹中搜索此dll 您可以将非托管dll文件复制到一个文件夹,然后将该文件夹添加到系统路径变量,也可以将这些文件复制到Windows\System32,因为该文件夹始终位于系统路径中 要修改系统路径,请右键单击“我的电脑”->“属性”->“高级系统设置”->“高级选项卡”->“环境变量”下的,在那里您需要找到路径变量,然后修改它以包含您的文件
将文件复制到Windows\System32或%systemroot%(C:\Windows通常)更容易,但我建议使用修改路径变量的方法。您可以将非托管dll文件复制到文件夹,然后将该文件夹添加到系统路径变量,也可以将这些文件复制到Windows\System32,因为此文件夹始终位于系统路径中 要修改系统路径,请右键单击“我的电脑”->“属性”->“高级系统设置”->“高级选项卡”->“环境变量”下的,在那里您需要找到路径变量,然后修改它以包含您的文件
不过,将文件复制到Windows\System32或%systemroot%(通常是C:\Windows)更容易,但我建议使用修改路径变量的方法,将它们保存在单独的文件夹中即可。您可以使用自己加载正确的仪器代理程序集。然后使用反射从该程序集创建类的实例并进行调用:
Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll");
Type yourClassType = assm.GetType("YourClass");
object yourClassObj = Activator.CreateInstance(yourClassType);
object Result = yourClassType.InvokeMember("DoSomething",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
yourClassObj,
args);
要避免反射调用InvokeMember
,您可以尝试使用接口:
Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll");
Type yourClassType = assm.GetType("YourClass");
YourInterface interf = (YourInterface)Activator.CreateInstance(yourClassType);
interf.DoSomething();
接口需要位于一个单独的程序集中,您可以从平台
引用该程序集。所有仪器代理
必须根据相同版本的接口组件进行编译
如果您的仪器代理找不到非托管instrument.dll
,您可以在首次使用之前显式加载它:
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
IntPtr pDll = LoadLibrary(@"PathTo_Instrument.dll");
完成后释放/卸载:
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
把它们放在不同的文件夹里就可以了。您可以使用自己加载正确的仪器代理程序集。然后使用反射从该程序集创建类的实例并进行调用:
Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll");
Type yourClassType = assm.GetType("YourClass");
object yourClassObj = Activator.CreateInstance(yourClassType);
object Result = yourClassType.InvokeMember("DoSomething",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
yourClassObj,
args);
要避免反射调用InvokeMember
,您可以尝试使用接口:
Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll");
Type yourClassType = assm.GetType("YourClass");
YourInterface interf = (YourInterface)Activator.CreateInstance(yourClassType);
interf.DoSomething();
接口需要位于一个单独的程序集中,您可以从平台
引用该程序集。所有仪器代理
必须根据相同版本的接口组件进行编译
如果您的仪器代理找不到非托管instrument.dll
,您可以在首次使用之前显式加载它:
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
IntPtr pDll = LoadLibrary(@"PathTo_Instrument.dll");
完成后释放/卸载:
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
像上面Maceij建议的那样,在单独的文件夹中部署您的工具。但是不要使用反射来加载/实例化这些工具,而是看看MEF 您的确切需求可能需要另一种方法来实现这一点,但我会使用以下方法让仪器代理
[Export]
实现仪器工厂接口:
IInstrument GetInstrument( string name, int major, int minor );
然后告诉MEF哪里可以找到您的仪器,让它创建不同的工厂,然后您可以从中请求所需的仪器
MEF上的MSDN:像上面Maceij建议的那样,将您的仪器部署在单独的文件夹中。但是不要使用反射来加载/实例化这些工具,而是看看MEF 您的确切需求可能需要另一种方法来实现这一点,但我会使用以下方法让仪器代理
[Export]
实现仪器工厂接口:
IInstrument GetInstrument( string name, int major, int minor );
然后告诉MEF哪里可以找到您的仪器,让它创建不同的工厂,然后您可以从中请求所需的仪器
MEF上的MSDN:对于.Net程序集,您可以在需要时使用assembly.LoadFrom(请参阅)订阅和加载程序集。对于.Net程序集,您可以在需要时使用assembly.LoadFrom(请参阅)订阅和加载程序集。是的,但我希望避免使用反射。例如,为了能够强制转换到YourClass,我需要有一个对dll的引用。用你的方法我负担不起,所以我需要对所有的电话进行反思,这是非常非常沉重的,我确实需要避免这种情况。我已经补充了一个问题,什么是理想的,理论上我需要你是对的。我已经更改了代码,但正如您所知,这都是反射。将考虑一个解决方案,但使用动态加载的程序集,这就是最终的结果。也许性能可以接受?值得一试。是的,但我想避免使用反射。例如,为了能够强制转换到YourClass,我需要有一个对dll的引用。用你的方法我负担不起,所以我需要对所有的电话进行反思,这是非常非常沉重的,我确实需要避免这种情况。我已经补充了一个问题,什么是理想的,理论上我需要你是对的。我已经更改了代码,但正如您所知,这都是反射。将考虑一个解决方案,但使用动态加载的程序集,这就是最终的结果。也许性能可以接受?值得一试。哇!这正是我想要的。事实上,在我尝试之前,我不相信你的答案。