AppDomain.CreateInstanceAndUnwrap 在网站中不起作用
Posted
技术标签:
【中文标题】AppDomain.CreateInstanceAndUnwrap 在网站中不起作用【英文标题】:AppDomain.CreateInstanceAndUnwrap not working in a website 【发布时间】:2012-04-27 17:59:43 【问题描述】:我有一个非常简单的类 CompiledFunction (MarshalByRefObject) - 我尝试在这样的新域中创建它的实例
var appDomainSetup = new AppDomainSetup();
appDomainSetup.ApplicationBase = Path.GetDirectoryName(typeof(CompilerService).Assembly.CodeBase);
var evidence = AppDomain.CurrentDomain.Evidence;
SandboxDomain = AppDomain.CreateDomain("Sandbox", evidence, appDomainSetup);
CompiledFunction<T> result = (CompiledFunction<T>)SandboxDomain.CreateInstanceAndUnwrap(
assemblyName: typeof(CompiledFunction<T>).Assembly.GetName().Name,
typeName: typeof(CompiledFunction<T>).FullName);
这在控制台应用程序中工作正常,但在 ASP .NET MVC 应用程序中我得到以下异常 - 任何人都可以提供任何建议,说明为什么这在 Web 应用程序中不起作用?我传递的 T 参数是 System.Decimal
System.IO.FileLoadException was caught
Message=The given assembly name or codebase, 'Ems.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null', was invalid.
Source=mscorlib
FileName=Ems.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
FusionLog==== Pre-bind state information ===
LOG: User = EMSLaptop\PeterMorris
LOG: DisplayName = Ems.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = /C:/Users/PeterMorris/Documents/Visual Studio 2010/Projects/MvcApplication26/MvcApplication26/bin
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Found application configuration file (C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.exe.Config).
LOG: Using application configuration file: C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL /C:/Users/PeterMorris/Documents/Visual Studio 2010/Projects/MvcApplication26/MvcApplication26/bin/Ems.Scripting.DLL.
StackTrace:
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Activator.CreateInstance(String assemblyName, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(String assemblyName, String typeName)
at System.AppDomain.CreateInstance(String assemblyName, String typeName)
at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
at Ems.Scripting.CompilerService.Compile[T](String[] scripts, Dictionary`2 variableDefinitions, IEnumerable`1 referencedAssemblies, ICompiledFunction`1& function, IEnumerable`1& compilerErrors) in C:\Data\EMS\Lib\Ems.Scripting\CompilerService.cs:line 43
InnerException:
【问题讨论】:
【参考方案1】:问题是 Assembly.Code 库以 file:///rest of path here 开头 - 在这样的路径上使用 Path.GetDirectoryName 时,它会用一个正斜杠替换 file:///;所以你最终得到“/c:\myfolder\myfile.dll”
让 Uri 告诉我本地路径是解决方案
if (SandboxDomain == null)
var appDomainSetup = new AppDomainSetup();
string appBase = typeof(CompilerService).Assembly.CodeBase;
//Added the following line
appBase = new Uri(appBase).LocalPath;
appDomainSetup.ApplicationBase = Path.GetDirectoryName(appBase);
var evidence = AppDomain.CurrentDomain.Evidence;
SandboxDomain = AppDomain.CreateDomain("Sandbox", evidence, appDomainSetup);
【讨论】:
您应该使用属性Location
而不是CodeBase
。【参考方案2】:
您似乎没有为 Web 项目正确复制 Ems.Scripting 程序集或为您的新域设置错误的 ApplicationBase(更有可能)。
Path.GetDirectoryName 调用在计算 ApplicationBase 属性时可疑。
【讨论】:
以上是关于AppDomain.CreateInstanceAndUnwrap 在网站中不起作用的主要内容,如果未能解决你的问题,请参考以下文章