文件加载异常:在InitializeComponent或x:Class处。

13
我在InitializeComponent方法处遇到了文件加载异常(第一次机会),或者调试器在多个WPF用户控件的xaml根部的x:Class属性处中断。尽管异常影响导航速度,但一切都正常运行。
以下是异常信息:
“无法加载文件或程序集'Company.Solution.UserInterface, Version=0.1.5568.25577, Culture=neutral, PublicKeyToken=45069ab0c15881ce'或其某一个依赖项。位于位置的程序集清单定义与引用程序集不匹配。(来自HRESULT的异常:0x80131040)”
以下是融合日志:
Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  D:\Development\Product\Main\src\Company.Product \bin\Debug\Product.vshost.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Company.Product .UserInterface, Version=0.1.5568.25577, Culture=neutral, PublicKeyToken=45069ab0c15881ce
(Fully-specified)
LOG: Appbase = file:///D:/Development/Product/Main/src/Company.Product/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.     
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\Development\Product \Main\src\Company.Product \bin\Debug\Product .vshost.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: Post-policy reference: Company.Product .UserInterface, Version=0.1.5568.25577, Culture=neutral, PublicKeyToken=45069ab0c15881ce
LOG: Attempting download of new URL file:///D:/Development/Product/Main/src/Company.Product/bin/Debug/Company.Product.UserInterface.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

我的项目结构有一个根项目,引用了一个模块项目(其中发生异常)。模块项目本身引用了上面提到的目标探测“Company.Product.UserInterface.dll”所包含的一些资源/控件/样式/基元/转换器等。

我如何摆脱这些FileLoadExceptions?

另一个更完整的Fusion-log:

=== Pre-bind state information ===
LOG: DisplayName = Company.Product.UserInterface, Version=0.1.5577.18122,      Culture=neutral, PublicKeyToken=45069ab0c15881ce
(Fully-specified)
LOG: Appbase = file:///D:/Development/Product/Main/src/Company.Product/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = Product.vshost.exe
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\Development\Product\Main\src\Company.Product\bin\Debug\Product.vshost.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: Post-policy reference: Company.Product.UserInterface, Version=0.1.5577.18122, Culture=neutral, PublicKeyToken=45069ab0c15881ce
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///D:/Development/Product/Main/src/Company.Product/bin/Debug/Company.Product.UserInterface.DLL.
LOG: Assembly download was successful. Attempting setup of file: D:\Development\Product\Main\src\Company.Product\bin\Debug\Company.Product.UserInterface.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Company.Product.UserInterface, Version=0.1.5577.18123, Culture=neutral, PublicKeyToken=45069ab0c15881ce
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: The assembly reference did not match the assembly definition found.
ERR: Run-from-source setup phase failed with hr = 0x80131040.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

在异常发生的时候,SolutionExplorer中引用的程序集版本为0.1.5577.18123(所有引用..UserInterface.dll的解决方案都是如此)。我不知道谁查找0.1.5577.18122,因为这个版本从未存在过。

如果我运行新的重建,我会得到相同的错误,Fusion会查找(我从未拥有过这个版本号):

LOG: Post-policy reference: Company.Product.UserInterface, Version=0.1.5577.18465, Culture=neutral, PublicKeyToken=45069ab0c15881ce

发现的版本为:
LOG: Assembly Name is: Company.Product.UserInterface, Version=0.1.5577.18466, Culture=neutral, PublicKeyToken=45069ab0c15881ce

Visual Studio的版本是2013 Ultimate,该项目构建于.net4.5上,并且程序集版本在构建过程中是自动生成的。 由于文件太大,我将构建日志上传到TinyUpload上了。 完整的Fusion-log可以在Pastebin上找到


1
UserInterface.dll 是否只被一个项目引用? - tchrikch
没有用户界面被3个项目使用,然后所有这些项目都由依赖根组合在一起。如果需要,我可以发布依赖图。 - quadroid
1
难道这三个项目中的一个引用了旧版本吗? - Bijington
没有任何项目使用相同的引用版本。 - quadroid
1
你是如何生成版本号的?我猜测它是自动生成的,因为从日志中可以看出版本号经常变化。如果是这种情况,那么似乎你的某个项目可能在 UserInterface 项目之前被构建了。我相当确定只有在一个项目引用 dll 而不是创建 dll 的项目时才可能发生这种情况。 - Bijington
显示剩余6条评论
2个回答

7
   Version=0.1.5577.18122

这个自动生成的版本号有一个故事,版本号的最后两部分并不是随意的。它们基于程序集构建的日期和时间。生成的构建号是从2000年1月1日以来的天数计算出来的。修订号是自午夜起没有进行夏令时调整的秒数乘以2。
因此,我们知道18122程序集是在3月30日下午2:12:34构建的。然后,它在2秒后的下午2:12:36又被构建了一次。在它被用作参考程序集构建另一个项目之后,CLR就会出现问题。
这种情况不应该发生,一个项目必须在单个构建会话中只构建一次。找出为什么会发生这种情况需要查看MSBuild跟踪。您可以通过“工具+选项”、“项目和解决方案”、“生成和运行”更改“MSBuild项目生成输出详细程度”设置来生成所需的跟踪。MSBuild现在会非常健谈,并告诉您为什么决定构建一个项目。如果您在尝试解码其输出时迷失在树林中(有很多输出),则将其复制/粘贴到paste-bin中,并在您的问题中链接到它。
否则没有那么多关于这种错误的好解释。旧的VS版本使得意外创建项目之间的循环依赖变得太容易。您可以使用“生成+清理”来解决这个问题。现在重新构建解决方案会失败,并告诉您哪个参考程序集是麻烦制造者。但您正在使用.NET 4,至少是VS2010。因此,这不是一个很好的线索,Microsoft添加了更多的检查来防止这种情况发生而没有警告。不确定它在所有情况下是否可靠,例如如果您不仅依赖于MSBuild。在具有“持续集成”功能的构建服务器上很常见。
我们需要构建跟踪来为您提供可靠的诊断。

版本号非常强烈地暗示着您正在忽略某些东西。您需要想出一种方法,在您的机器上这个程序集在2秒内被构建了两次。我想从技术上讲,连续两次点击“生成”可能是可行的。但是如果您不向我们展示任何东西,那么就没有线索可寻。比如构建跟踪信息。 - Hans Passant
我在我的问题中添加了构建跟踪。 - quadroid
我看到了一些小问题,但没有什么特别严重的。有一个细节很有趣,你的项目存储在D盘上。这是什么类型的驱动器?2秒钟是文件系统的魔数,它是FAT32驱动器的时间戳分辨率。 - Hans Passant
这是一个NTFS格式的SSD(没有任何物理设备,只是一个分区)。 - quadroid
我已经没有其他的理论了。我唯一能推荐的是不要依赖于自动生成的版本。请编辑项目的AssemblyInfo.cs文件并将 [assembly: AssemblyVersion("0.1.*")] 改为 "0.1.0.0"。 - Hans Passant
显示剩余2条评论

1

建议1

是否存在循环引用导致加载旧版本的dll?(这已被证明不是问题,但出于历史原因我仍然保留了它)。 与此答案相关

建议2

您可以尝试创建一个发布者策略吗? 以下是需要添加到您的app.config文件中的示例。

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Company.Solution.UserInterface"
                        publicKeyToken="45069ab0c15881ce"
                        culture="en-us" />
      <!-- Redirecting to version 0.1.5568.25577 of the assembly. -->
      <bindingRedirect oldVersion="0.0.0.0-0.1.5568.25577"
                      newVersion="0.1.5568.25577"/>
    </dependentAssembly>
  </assemblyBinding>
</runtime>

在这里进一步解释

建议3

签署您的程序集所使用的密钥是否发生了任何变化?

建议4

作为我最初建议的轻微改编。您已经说明有3个项目引用了Company.Solution.UserInterface。您能确认这3个项目是否都引用了同一个版本的该程序集吗?


@控制台 可能不一定是循环引用,但从错误信息来看,似乎您正在加载与项目期望的版本不匹配的版本。如果您在VS中检查引用,它是否将“特定版本”设置为True? - Bijington
你检查过全局程序集缓存(GAC)中没有旧版本了吗? - Bijington
2
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。 - bit
1
@bit 我已经改进了我的答案。 - Bijington
绑定重定向并未解决问题,关键是从未更改过。 - quadroid
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接