给DNN装SkinTuner扩展时出现Could not load file or assembly 'System.Data.SQLite
一、昨天晚上摆弄Dotnetnuke到四点,最后在装一个SkinTuner的皮肤(调试)控制器时,出现严重错误导致无法浏览管理网站:
Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.
二、为了查看详细错误,用ftp工具将web.config下载下来修改 <customErrors mode="RemoteOnly" />为 <customErrors mode="Off" />显示如下详细错误:
Unverifiable code failed policy check. (Exception from HRESULT: 0x80131402)
Stack Trace:
[FileLoadException: Unverifiable code failed policy check. (Exception from HRESULT: 0x80131402)]
[FileLoadException: Could not load file or assembly 'System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139' or one of its dependencies. Unverifiable code failed policy check. (Exception from HRESULT: 0x80131402)]
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +39
System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks) +132
System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +144
System.Reflection.Assembly.Load(String assemblyString) +28
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46
[ConfigurationErrorsException: Could not load file or assembly 'System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139' or one of its dependencies. Unverifiable code failed policy check. (Exception from HRESULT: 0x80131402)]
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +618
System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +209
System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +130
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178
System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +94
System.Web.Compilation.BuildManager.CallPreStartInitMethods() +332
System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +591
[HttpException (0x80004005): Could not load file or assembly 'System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139' or one of its dependencies. Unverifiable code failed policy check. (Exception from HRESULT: 0x80131402)]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8946484
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256
三、可以看出,根本原因是 Could not load file or assembly 'System.Data.SQLite,可以断定,最后安装的SkinTuner使用的SQLite,查看安装色发现果然有System.Data.SQLite.dll,在网站里也找到了System.Data.SQLite.dll,但却无法加载,为什么呢?搜索ould not load file or assembly 'System.Data.SQLite找到答案,我正好用的godaddy.com的空间,这一错误是godaddy的限制造成的!:
System.Data.SQLite.dll是无法在godaddy的服务器上使用的。原因是godaddy的ASP.NET2.0及以上的IIS使用了“信任级别”的限制:TrustLevel=”Medium”,也就是说,很多第三方的dll将无定法在这个级别下运行。必须把TrustLevel设置为”Full”,才可以使用。但是出于安全考虑godaddy一般不会开发这个信任级别。
为什么TrustLevel=”Medium”,就无法使用System.Data.SQLite.dll,是因为当服务器设置了TrustLevel=”Medium”之后,要求运行的dll必须是“完全托管代码”(pure managed code),并且不能包含任何的 P/Invoke调用或使用任何的原始API(raw API)调用。不幸的是,System.Data.SQLite.dll使用了P/Invoke调用。所以无法跑在TrustLevel=”Medium”级别下。
如果一定要使用SQLite数据库的话,方法是有的:
1、使用ASP.NET1.1(当然这样就没法使用很多东西,包括EF层面上的)
2、使用“托管代码”(managed code)的Sqlite数据库,这里有一个可以使用:http://code.google.com/p/managed-sqlite/
为什么TrustLevel=”Medium”,就无法使用System.Data.SQLite.dll,是因为当服务器设置了TrustLevel=”Medium”之后,要求运行的dll必须是“完全托管代码”(pure managed code),并且不能包含任何的 P/Invoke调用或使用任何的原始API(raw API)调用。不幸的是,System.Data.SQLite.dll使用了P/Invoke调用。所以无法跑在TrustLevel=”Medium”级别下。
如果一定要使用SQLite数据库的话,方法是有的:
1、使用ASP.NET1.1(当然这样就没法使用很多东西,包括EF层面上的)
2、使用“托管代码”(managed code)的Sqlite数据库,这里有一个可以使用:http://code.google.com/p/managed-sqlite/
四、下载http://managed-sqlite.googlecode.com/svn/branches/bin/1.0.0.1340/ManagedSQLite.zip后改名为System.Data.SQLite.dll,上传到网站bin目录下
结果出现如下错误:
Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Assembly Load Trace: The following information can be helpful to determine why the assembly 'System.Data.SQLite' could not be loaded.
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
Stack Trace:
[FileLoadException: Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +39
System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks) +132
System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +144
System.Reflection.Assembly.Load(String assemblyString) +28
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46
[ConfigurationErrorsException: Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +618
System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +209
System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +130
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178
System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +94
System.Web.Compilation.BuildManager.CallPreStartInitMethods() +332
System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +591
[HttpException (0x80004005): Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8946484
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256
五、The located assembly's manifest definition does not match the assembly reference 原来是版本不匹配造成的,版本设置或检查是在哪里进行的呢,是SkinTuner里的文件设置的(搜索了所有安装文件没找到)还是由dnn系统检查的(若是,在哪里我也不清楚,网上没搜到)。
于是我有个想法:先想办法使网站恢复正常-卸载SkinTuner-将SkinTuner.zip里的System.Data.SQLite.dll替换成纯托管代码版的-再安装,看看能不能自动识别版本以注册。(有这些想法都是由于对具体注册机制不了解),结果还是和上面的错误一样,同校的方法,不过这次替换成官方最新版SQLite,这次没有出错(难道最新版已经使用完全托管的代码了?),但是在页面上添加该模块后,在模块里提示了版本不匹配的错误,难道要暴力修改SQLite不成,算了懒得弄了,SkinTuner倒底有多大用处都不清楚,干脆卸载了SkinTuner。
虽然没有能成功运行SkinTuner,但起码在实践中解决了这种情况下网站无法访问的问题,也许安装其它扩展出现此类问题时可如法炮制。