C# 加载DLL的AppDomain代码在VB中工作,但在C中不工作#
不久前,我用VB编写了一个程序(称为QueryViewer),作为它的一部分,它将DLL加载到一个新的应用程序域中并成功地执行它们。后来我转到了C#,并将这个程序从VB转换为C#,但我一直无法得到我认为正确转换的C#例程。它在appdomain.CreateInstanceAndUnwrap调用中总是失败,即使此代码(在VB中)工作正常 下面是运行的原始VB代码:C# 加载DLL的AppDomain代码在VB中工作,但在C中不工作#,c#,.net,vb.net,C#,.net,Vb.net,不久前,我用VB编写了一个程序(称为QueryViewer),作为它的一部分,它将DLL加载到一个新的应用程序域中并成功地执行它们。后来我转到了C#,并将这个程序从VB转换为C#,但我一直无法得到我认为正确转换的C#例程。它在appdomain.CreateInstanceAndUnwrap调用中总是失败,即使此代码(在VB中)工作正常 下面是运行的原始VB代码: Imports System.Reflection Imports System.Security Imports System.S
Imports System.Reflection
Imports System.Security
Imports System.Security.Policy
Imports System.Security.Permissions
Public Class ClassLocalLoader
Inherits MarshalByRefObject
Private _appDomain As AppDomain
Private _clsRemoteLoader As classRemoteLoader
Public Sub New()
Dim strAsmName As String
Dim adSetup As AppDomainSetup
Try
strAsmName = [Assembly].GetExecutingAssembly.GetName.Name
adSetup = New AppDomainSetup()
adSetup.ApplicationName = "Plugin"
adSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
Dim permSet As PermissionSet = New PermissionSet(PermissionState.None)
permSet.AddPermission(New SecurityPermission(SecurityPermissionFlag.AllFlags))
Dim ev As Evidence = New Evidence()
ev.AddHostEvidence(New Zone(SecurityZone.MyComputer))
permSet = SecurityManager.GetStandardSandbox(ev)
_appDomain = AppDomain.CreateDomain("Plugin", Nothing, adSetup, permSet, New StrongName() {})
_clsRemoteLoader = CType(_appDomain.CreateInstanceAndUnwrap(strAsmName, strAsmName & ".ClassRemoteLoader"), classRemoteLoader)
Catch logerrorex As Exception When TCA.Display.ShowLine(logerrorex)
Catch ex As Exception
End Try
End Sub
Public Sub LoadAssembly(ByVal strFilename As String)
_clsRemoteLoader.LoadAssembly(strFilename)
End Sub
Public Function CreateInstance(ByVal bindingFlags As BindingFlags, ByVal constructorParams As Object()) As MarshalByRefObject
Return _clsRemoteLoader.CreateInstance(bindingFlags, constructorParams)
End Function
Public Sub Unload()
If _appDomain IsNot Nothing Then
AppDomain.Unload(_appDomain)
_appDomain = Nothing
End If
End Sub
End Class
现在,这里是转换后的C代码,它不会:
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using KellermanSoftware.NetLoggingLibrary;
public class ClassLocalLoader : MarshalByRefObject
{
private AppDomain _appDomain;
private ClassRemoteLoader _classRemoteLoader;
public ClassLocalLoader()
{
try
{
String asmName = Assembly.GetExecutingAssembly().GetName().Name;
var adSetup = new AppDomainSetup
{
ApplicationName = "Plugin",
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
};
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
Evidence ev = new Evidence();
ev.AddHostEvidence(new Zone(SecurityZone.MyComputer));
permSet = SecurityManager.GetStandardSandbox(ev);
if (permSet != null)
{
_appDomain = AppDomain.CreateDomain("Plugin", null, adSetup, permSet);
_classRemoteLoader = (ClassRemoteLoader)_appDomain.CreateInstanceAndUnwrap(asmName, asmName + ".ClassRemoteLoader");
}
}
catch (Exception ex)
{
Log.LogExceptionEx(ex, "Exception raised while trying to load plugin.");
}
}
public void LoadAssembly(string filename)
{
Assembly.LoadFrom(filename);
}
public MarshalByRefObject CreateInstance(BindingFlags bindingFlags, Object[] constructorParams)
{
return _classRemoteLoader.CreateInstance(bindingFlags, constructorParams);
}
public void Unload()
{
if (_appDomain != null)
{
AppDomain.Unload(_appDomain);
_appDomain = null;
}
}
}
C#代码失败,出现以下错误:
无法从程序集“QueryViewer,版本=1.4.0.0,区域性=中立,PublicKeyToken=null”加载类型“QueryViewer.ClassRemoteLoader”
导致故障的调用如下所示:
classLocalLoader = new ClassLocalLoader();
有人看到我转换后的C#例程有什么问题会导致失败吗
谢谢,
Don B.您是否已通过这两组代码来比较传递到
\u appDomain.CreateInstanceAndUnwrap的值,以查看是否有任何问题?存在一些明显的差异:1。分配给_appDomain的方式与原始VB不同。2.在最初的VB代码中调用_clsRemoteLoader.LoadAssembly,但在C代码中调用Assembly.LoadFrom。转换时应尽量保持常量,以便更容易地隔离问题。遗憾的是,错误发生在createinstanceandunwrap调用上,并且由于VS2015错误导致无法查看瞬态数据或类似错误,因此无法检查_appDomain的值。所以,不,我看不出有什么不同。是的,你是对的,我将修复并重试。但是请注意,我从未访问过loadfrom函数,因为它在类实例化中失败。您是否已通过这两组代码来比较传递到\u appDomain.CreateInstanceAndUnwrap
的值,以查看是否有任何问题?有一些明显的区别:1。分配给_appDomain的方式与原始VB不同。2.在最初的VB代码中调用_clsRemoteLoader.LoadAssembly,但在C代码中调用Assembly.LoadFrom。转换时应尽量保持常量,以便更容易地隔离问题。遗憾的是,错误发生在createinstanceandunwrap调用上,并且由于VS2015错误导致无法查看瞬态数据或类似错误,因此无法检查_appDomain的值。所以,不,我看不出有什么不同。是的,你是对的,我将修复并重试。但是请注意,我从未访问过loadfrom函数,因为它在类实例化中失败。