6

我有一个解决方案,我正在尝试从 .NET 2 转换为 .NET 4。此解决方案中有多个项目,其中一些使用 C#,其中一些使用 VB。他们中的大多数使用 system.xml 来创建和解析 XML。

我已将所有项目重新定位到 .NET 4,并且可以编译。但是,当我尝试运行时,我几乎立即收到 System.FieldAccessException,说“如果类库中某个字段的访问级别已更改,请重新编译引用该库的所有程序集。”。在此之前我确实重新编译了整个解决方案(之后再次尝试,没有改变)。

然后我使用程序集绑定日志查看器查看是否有任何绑定失败,因为当它引用项目中的不同 dll 时会发生这种情况。果然,那里有失败。它们在两个不同的 VB 项目中,它们看起来都像这样:


The operation failed. 
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll 
Running under executable  <path to my exe>
--- A detailed error log follows. 

=== Pre-bind state information === 
LOG: DisplayName = <projname>.XmlSerializers, Version=2013.20.0.0, Culture=neutral, PublicKeyToken=null, processorArchitecture=MSIL  (Fully-specified) 
LOG: Appbase = <projectpath> 
LOG: Initial PrivatePath = NULL 
LOG: Dynamic Base = NULL 
LOG: Cache Base = NULL 
LOG: AppName = <projname>.vshost.exe Calling assembly : System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
=== LOG: This bind starts in default load context. 
LOG: Using application configuration file: <project path\config file> 
LOG: Using host configuration file:  
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\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 file:///<project path>/<projname>.XmlSerializers.DLL. 
LOG: Attempting download of new URL file:///<project path>/<projname>.XmlSerializers/CMG.XmlSerializers.DLL. 
LOG: Attempting download of new URL file:///<project path>/<projname>.XmlSerializers.EXE. 
LOG: Attempting download of new URL file:///<project path>/<projname>.XmlSerializers.EXE. 
LOG: All probing URLs attempted and failed.

果然,我的 obj 文件夹中没有任何这样的文件。但以前也没有,而且效果很好。(注意:这些绑定错误只出现在两个使用 XML 的 VB 项目中,而不是 C# 项目中。)我删除并重新添加了对 system.xml 的引用,清理了解决方案并重新构建了 - 仍然没有。

我检查了 system.xml v4 在 GAC 中,公钥与它在这里寻找的相同。我在构建选项卡上看到了对名为“生成序列化程序集”的项目选项的引用。在 VB 项目中,它位于编译 > 高级选项下。它被设置为自动。我尝试打开它,重建它,但没有任何变化。我不确定下一步该往哪里看——这对我来说是全新的领域。那么这个文件应该从哪里来,为什么它不在那里,为什么它在没有它的情况下在 v2 中工作?还是所有这些 xml 内容都是红鲱鱼,与原始问题无关?我开始担心这一点,但目前还不能确定任何一种方式。任何指导将不胜感激。

ETA:如果我在 VS 之外运行它,错误日志会将崩溃显示为事件 1000,并带有“故障模块名称:kernelbase.dll”。到目前为止,我在这方面所做的搜索表明在 64 位操作系统上运行的 32 位应用程序存在问题,但我已经将整个东西设置为编译为 Any CPU。事实证明,当我运行 .NET 2 版本时,我也看到了相同的绑定错误,即使它在那里运行良好。我开始越来越多地认为 XML 是一条红鲱鱼。

进一步的 ETA:XML 事情确实是一个红鲱鱼。添加了解决方案作为下面的答案。

4

1 回答 1

2

所以毕竟是保安。根据http://msdn.microsoft.com/en-us/library/stfy7tfc.aspx

如果成员具有 SecurityCriticalAttribute,如果它属于具有 SecurityCriticalAttribute 的类型,或者如果它位于安全关键程序集中,则该成员是安全关键的。从 .NET Framework 4 开始,访问安全关键成员的规则如下:

即使代码完全受信任,透明代码也不能使用反射来访问安全关键成员。引发 MethodAccessException、FieldAccessException 或 TypeAccessException。

以部分信任运行的代码被视为透明的。

进一步阅读,我发现随着 .NET 4 的这种变化,他们实际上为这些规则引入了 2 个级别 - 级别 2 是这些新规则,级别 1 是 .NET 2 规则,用于向后兼容。我通过添加以下内容来设置无法使用 1 级规则的程序集:

<Assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)> 

到 AssemblyInfo.vb 文件(并添加 system.security 作为参考)。现在一切正常。显然,理想的做法是将其更改为使用 2 级规则,但这是在路上。这至少不仅暂时解决了问题,而且告诉我确切的问题是什么。感谢大家!

于 2013-08-16T23:02:16.493 回答