Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 引用.net dll+;非托管dll 我有一个项目(称为平台)引用.NETDLL(调用IT工具代理),使用dLimPART(调用IT工具)引用C++ DLL。仪器及其代理始终是同一版本,并且始终作为一个版本部署_C#_.net_Dllimport - Fatal编程技术网

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的引用。用你的方法我负担不起,所以我需要对所有的电话进行反思,这是非常非常沉重的,我确实需要避免这种情况。我已经补充了一个问题,什么是理想的,理论上我需要你是对的。我已经更改了代码,但正如您所知,这都是反射。将考虑一个解决方案,但使用动态加载的程序集,这就是最终的结果。也许性能可以接受?值得一试。哇!这正是我想要的。事实上,在我尝试之前,我不相信你的答案。