项目引用 DLL 版本混乱问题

21

我们遇到了一个问题,无法让Visual Studio从我们项目中的一个DLL文件夹中获取最新版本的DLL。

我们有多个类库项目(例如BusinessLogic、ReportData)和一些Web服务,每个项目都引用了我们编写的Connectivity DLL(这个引用是问题所在)。

我们总是将引用指向bin/debug文件夹中的DLL(对于任何给定的项目,我们总是构建到此处),所有自定义DLL引用都具有CopyLocal=True和SpecificVersion=False。

ReportData引用了business logic(它也引用了connectivity——我不知道为什么会出现问题,但认为值得一提)。

奇怪的是,当你点击“添加引用”并浏览到Connectivity/bin/debug文件夹时,当你将鼠标悬停在DLL文件上时,正确的(最新的)版本就会显示出来(版本和文件版本始终一起递增),但当你点击“确定”时,会引入一个旧版本号。即使我查看当前项目的debug文件夹(复制本地在编译后会将DLL放置在此处),它也显示最新版本号。没有任何地方可以找到旧版本的DLL文件,但在该项目引用中,它拥有旧版本 - 即使路径是正确的。

我不知道它可能从哪里获取旧版本,甚至也不知道为什么要使用旧版本。

这可能是我遇到的最令人沮丧的问题。

有谁知道如何确保获取最新版本(最好是自动或在编译时)?

编辑:

虽然不完全是我所处理的情况,但我正在阅读文章,在其中某处提到CLR会忽略修订号。可以理解(即使以前没有出现过这个问题——我们在第39次修订),所以我想我会更新构建号,但仍然无法解决问题。最后我试图更新小版本号,看看是否有任何区别。

我并不是说这就是解决方案,因为我还需要先检查很多东西,但表面上看起来,这似乎已经解决了我的问题...

进一步编辑: 在其他类库中,这似乎已经解决了问题,然而在一个测试窗口应用程序中,它仍然会拉取以前的版本 :(

如果我再次增加小版本号,同样的问题会再次出现,我将得到错误的版本。

进一步编辑——我创建了一个全新的项目,添加了一个引用,但仍然遇到了完全相同的问题。这表明问题局限于我正在引用的项目中。但愿我知道原因!

有人之前遇到过这个问题并知道如何解决吗?

求助!


按任何特定顺序构建项目(例如,先构建BusinessLogic再构建ReportData)似乎没有帮助。 - Mr Shoubs
你是否在使用文件引用来引用解决方案中的程序集?或者Connectivity.dll是在另一个解决方案中构建的吗? - Timores
它是另一个解决方案的一部分。 - Mr Shoubs
10个回答

38
为了避免“dll hell”,我建议您在项目中创建一个“lib”文件夹,并将所有共享的程序集放入其中。然后,只从该文件夹中添加引用。这样,您的项目是自包含的,您可以确切知道引用是从哪里获取的。如果您想使用新版本更新某个程序集,则将其复制到“lib”文件夹中并重新构建项目即可。
同时,请确保不要将引用的程序集放入全局程序集缓存(GAC)中,因为它们可能会首先被选中。

+1,...并确保在Visual Studio中对每个共享引用勾选本地选项。 - Johannes Rudolph
这是一个好主意,但是没成功 :( 它可能从哪些地方获取到先前的版本呢?我检查了三遍,复制了正确的文件。 - Mr Shoubs
它不在GAC中,但是在.NET选项卡中...我个人认为,如果程序集的主要版本错误,构建应该失败。 - Mr Shoubs
3
如果全局程序集缓存中没有该程序集的版本,并且您已从项目的“引用”列表中删除了对该库的引用,然后重新将其添加以指向/lib文件夹中的dll文件,除非您没有为所有引用了该DLL的解决方案中的所有项目执行相同的操作,否则该版本不可能是除该文件夹中的内容以外的任何内容。每个需要引用该DLL的项目都需要使用本地/lib文件夹。 - Thomas
我非常确定这不是问题所在,但既然你已经接近隧道的尽头,你是否确认你正在查看程序集版本而不是文件版本?你能确认文件版本和程序集版本是相同的吗?另外,你能否在程序集中包含一个新方法并查找新方法是否可用,只是为了测试? - Wagner Silveira
显示剩余5条评论

9

你可以尝试以下几个选项:

  1. 编译项目并在输出窗口查看程序集路径,以确保引用的位置正确。
  2. 重新编译前删除 Obj 文件夹。
  3. 关闭并重新打开 Visual Studio,因为VS会有一些奇怪的行为来保持缓存以保留DLL引用。
  4. 如果问题仍然存在,使用此工具检查参考程序集的实际来源。 Process Explorer

我会在风格上投赞成票,但我还没有15个声望点。1 - 显示正确的路径 2 - 似乎完全没有任何区别 3 - 已经完成,有时这确实可以解决一些编译问题,但不是这个问题 4 - 我找不到进程资源管理器中告诉我这个信息的位置。 - Mr Shoubs
  1. 我想我忘了提到这一点,编译并运行应用程序,您可以在输出窗口中看到它从哪里加载。
  2. 正如Darin所提到的,最好将其保存在共享文件夹中。这样,您可以删除bin和obj文件夹,以始终重新生成可执行文件,以确保我们使用应用程序的新副本运行。
  3. 您提到它从某个地方选择了错误的程序集,对于此工具,您可以查看应用程序的引用程序集,并在运行时查看它从哪里加载以及其版本号等信息。
- sankar
此外,用记事本打开您的项目文件,检查是否存在硬编码的版本号或者提示路径。如果有的话,请删除它们并添加正确的版本号。 - sankar
这里有一段程序相关的内容需要翻译成中文:<Reference Include="VHC.Connections, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>......\vhc.server.solution\vhc.connections\Tags\v_3_0_0_5\bin\Debug\VHC.Connections.dll</HintPath> </Reference> 但是更改它并没有任何影响。 - Mr Shoubs
好的,你使用了Process Explorer工具吗? - sankar
在进程资源管理器中,我找不到引用程序集的位置 - 我右键单击应用程序,点击属性,在那里没有关于引用程序集的任何信息... - Mr Shoubs

8
为了解决这个问题,我删除了所有引用,然后重新添加它们。我不知道为什么这是解决方案。
可能在一个项目中,一个DLL文件是错误的,而正是这个错误的DLL被Visual Studio调用并使用了。
编辑: 其他情况下,此错误的发生是由于当前项目中引用的DDL文件(A)也被另一个DLL文件(B)引用。没有重建另一个DLL文件(B),似乎会防止VS在当前项目中引用正确版本的DLL文件(A),从而带来DLL文件(A)的旧版本。

1
我认为这个方法可行是因为当引用被添加到项目中(通过Visual Studio),版本元数据会记录在<Reference/>行中。我遇到了同样的问题,发现卸载项目、找到引用并手动更改版本信息可以让项目“找到”新版本的DLL。 - Zach Young
对我有用,我删除了所有的obj和bin文件夹,移除了项目之间的引用,清理了一下,重新构建,重新添加了引用。Booyaa。 - Sam Jones
对我有用!如果您正在使用发布文件夹,则最好在发布之前删除所有内容,以确保文件被添加而不是替换! - revobtz
@revobtz - 如果你正在使用文件发布功能,我认为在设置中(文件发布选项)有一个选项可以自动“在发布之前删除所有现有文件”。 - Mr Shoubs
@MrShoubs 是的,我已经知道了,但有时候人们不知道这个。因此,我只是想要确保他们获取新文件而不是替换旧文件。非常感谢您的评论,它可能会帮助其他人! - revobtz

2
您尝试过将引用添加为项目引用吗?即添加引用... -> 项目选项卡 -> 选择您的项目。

很遗憾,在我们的情况下这是不可能的,我们必须引用DLL文件。(我希望情况不是这样) - Mr Shoubs

2
我们(特指我,因为我是我们团队唯一的.NET开发人员)遇到了完全相同的问题。我将其追踪到一个被引用的dll,而这个dll又引用了患有版本问题的dll。似乎是因为我没有更新所有引用该dll的引用,导致在构建过程中某个时刻被旧版本替换了。
我遇到的其中一个症状是,在代码编辑器中,我添加到引用项目中的新类会被正确地着色,但当我点击“生成”时,它会变回黑色,并显示一个消息说该类不存在(附带一个非常讽刺的“你是否缺少程序集引用?”)。这使我相信问题必须发生在“生成”阶段。
因此,我建议构建任何和所有其他指向此DLL的项目,并重新添加它们的引用。

0

0

我曾经遇到过类似于这里描述的问题,但我的解决方案与我编译代码的方式有关。Build、Clean和Rebuild之间有区别。在我的情况下,我只是在更改后使用了Build,导致依赖解决方案的dll没有随着所有更改一起传递到其他设置引用的解决方案中。我通过使用Rebuild解决了这个问题,它会清理、编译和链接所有源文件,无论它们是否发生了更改。然后第一个解决方案的dll被更新并自动复制到设置引用的第二个解决方案中,问题得到了解决。 祝好,希望这可以帮助你。


0

请查看以下内容:

  1. 如果有问题的dll被主机Web应用程序和其引用的应用程序引用。例如,您的Web应用程序使用abc.dll(有问题的)和另一个dll xyz.dll(即类项目,也引用abc.dll)。

在这种情况下,假设您已将abc.dll从版本1更新到版本2并重新引用到您的Web应用程序中。但是在构建过程中,abc.dll的版本2将会改回版本1,因为xyz.dll使用版本1,并且Web应用程序在xyz.dll的自动更新期间将abc.dll版本2覆盖回abc.dll版本1。

解决方案:在xyz.dll的类项目bin中也放置abc.dll版本2的更新版本。

希望以上详细信息能够帮助您,祝您好运。


0

可能的原因之一是参考路径。如果有任何对旧dll文件夹的引用,即使您添加了新的dll引用,VS也会将其用作主要引用。


0

启用FusionLog,当DLL无法加载时,在文件夹C:\FusionLog\Default\devenv.exe中打开与DLL名称相同的文件。这将显示DLL实际加载的路径。

在我的情况下,一个旧版本神秘地出现在

C:\Program Files\Microsoft Visual Studio 10\Common7\IDE!

为了防止这种情况再次发生,我在Common7\IDE上添加了一个“拒绝写入”安全规则,适用于所有人。


1
如果你启用了Fusion程序集绑定日志记录,请确保在调试完程序集加载问题后将其禁用! - Dave Black
@smirkingman 在我的情况下,它位于 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root. 我已经从 Temporary ASP.NET Files 中删除了所有内容,并进行了一次干净的项目,但它仍然试图从相同的位置加载。有什么想法吗? - Ammar Khan

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