前段时间,我在VB中编写了一个程序(称为QueryViewer),作为其中的一部分,将dll加载到新的应用程序域并成功执行它们。我已经转移到C#并将这个程序从VB转换为C#但是我从来没有能够得到我认为正确转换的C#例程。它始终在appdomain.CreateInstanceAndUnwrap调用上失败,即使这段代码(在VB中)也能正常工作。
这是原始的VB代码:
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,Version = 1.4.0.0,Culture = neutral,PublicKeyToken = null”加载类型“QueryViewer.ClassRemoteLoader”。
导致失败的调用如下:
classLocalLoader = new ClassLocalLoader();
任何人都认为我转换的C#例程有什么问题会导致这种情况失败?
谢谢, 唐B。