Visual Studio 2010始终认为项目已过期,但实际上没有任何更改。

197

我有一个非常类似于这里描述的问题。

我也将一个包含C++/CLI和C#工程的混合解决方案从Visual Studio 2008升级到了Visual Studio 2010。在Visual Studio 2010中,一个C++/CLI工程总是过期。

即使它已经在编译和链接之前完成,按下F5,消息框"该项目已过期。您想要构建它吗?"会出现。这非常烦人,因为DLL文件是低级别的,强制几乎所有的解决方案重新构建。

我的pdb设置被设置为默认值(此问题的建议解决方案)。

是否有可能找到Visual Studio 2010强制重建或认为某个工程是最新的原因?

其他任何关于Visual Studio 2010出现这种情况的想法?


请参考以下链接:https://dev59.com/O43da4cB1Zd3GeqPxEDH - newdazhu
请参考以下链接:https://dev59.com/O43da4cB1Zd3GeqPxEDH - newdazhu
30个回答

225

仅适用于Visual Studio/Express 2010。对于VS2012、VS2013等版本,请参见其他(更简单的)答案。

要找到缺失的文件,请使用文章Enable C++ project system logging中的信息,在Visual Studio中启用调试日志记录,让它“告诉你”何为重新构建的原因:

  1. 打开devenv.exe.config文件(在%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE\%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\中找到)。对于Express版本,配置文件命名为V*Express.exe.config
  2. </configSections>行之后添加以下内容:

    <system.diagnostics>
      <switches>
        <add name="CPS" value="4" />
      </switches>
    </system.diagnostics>
    
  3. 重新启动Visual Studio
  4. 打开DbgView并确保其捕获调试输出
  5. 尝试进行调试(在Visual Studio中按F5)

  6. 在调试日志中搜索以下形式的任何行:

    devenv.exe Information: 0 : 由于构建输入“Bla\Bla\SomeFile.h”丢失,项目“Bla\Bla\Dummy.vcxproj”不是最新的。

    (我刚才按Ctrl+F并搜索了not up to date),这些将是导致项目永远处于“过时”状态的引用。

要纠正此问题,可以从您的项目中删除任何对缺失文件的引用,或者更新引用以指示其实际位置。

注意:如果使用2012或更高版本,则代码段应为:

<system.diagnostics>
  <switches>
   <add name="CPS" value="Verbose" />
  </switches>
</system.diagnostics>

4
打开 DbgView 并确保它正在捕获调试输出。 如何确保已开始捕获?我遇到了重新构建项目的相同问题。但是 DebugView 中没有任何信息。我在 DebugView 的“Capture”菜单中启用了前 5 个选项。(感谢提供有用链接的回答!) - sergtk
3
这帮助我们弄清了问题的所在;然而,在最后一个 .H 引用消失之前,我们还需要删除中间生成的构建目录——可能是为了刷新 StdAfx.obj?总之,在删除了所有中间生成的构建文件夹并整理了项目文件后,我们也可以顺利进行。 - AHelps
2
谢谢 - 现在为什么不在常规输出窗口中呢? - Martin Beckett
4
如果您使用的是VS2012,那么需要复制一个稍微不同的代码片段到配置文件中。这个在原始文章中有链接,但以防万一,这里是链接:启用VS2012的C++和Javascript项目系统跟踪 - rmaVT
3
FYI,这个方法似乎在VS2013中已经无法使用了 - 编辑配置文件后,在DebugView中不会生成任何感兴趣的内容。 翻译:提供信息,这种方法在VS2013中似乎不再起作用了 - 编辑配置文件后,在DebugView中不会生成任何有趣的内容。 - Nathan Reed
显示剩余11条评论

166

在Visual Studio 2012中,我比接受的解决方案更容易地实现了相同的结果。

我在菜单工具选项项目和解决方案构建和运行→*MSBuild项目构建输出详细程度" 中更改了选项,从最小更改为诊断

然后,在构建输出中,通过搜索 "not up to date"找到了相同的行:

项目“blabla”不是最新的。项目项“c:\foo\bar.xml”已将“复制到输出目录”属性设置为“始终复制”。


6
这在VS2013中也适用,但似乎不再起作用了。 - Nathan Reed
7
使用C#,我找不到任何带有“没更新”的内容,关键词似乎是“比...更新”。 - Pete
3
由于构建输入 'C:\ ... \ ReadMe.txt' 丢失,项目不是最新的。 - jozxyqk
1
太棒了,即使使用完整的日志记录,首先决定构建项目,因此您不必使用此方法搜索数千个日志条目以找到解决方案 :-) 对我来说也是一样的,将复制到输出目录设置为始终而不是如果更新。 - Tony Wall
3
在VS2013中,您也可能需要在诊断模式下搜索“was modified at”,因为我没有看到“not up to date”的输出。 - jaba
显示剩余5条评论

60
今天我遇到了这个问题。我找到了原因:项目包含一个在磁盘上不存在的头文件。
从项目中删除该文件解决了问题。

2
不,我没有任何在磁盘上不存在的头文件。 但是你是如何追踪到原因的呢?你是怎么发现有一个文件丢失了呢? 也许我可以通过类似你的方式来检查,以便找出更多关于我的问题的信息。 - Chris U
1
当我遇到这个问题时,有一个不同的解决方案。可能相当晦涩,但我从一台计算机编译项目,然后从另一台计算机编译,并发现我在一台计算机上意外地将时间设置为上午,而在另一台计算机上设置为下午。这种极端的时间差导致其中一台计算机要么始终编译所有内容,要么即使我修改了源文件也不会编译任何内容。 - Kyle
1
尽管头文件存在,但这对我起作用了。使用下面的答案启用日志记录时,它认为缺少一个头文件。我删除了它的依赖项,重新添加了它,并且最小重建又可以工作了! - Ed Bayiates
时钟偏差会导致大多数构建系统崩溃。 - paulm

15
我们也遇到了这个问题,并找到了解决方法。
问题如上所述:“磁盘上的文件已不存在。”
但实际上文件确实存在于磁盘上,只是 .VCPROJ 文件引用该文件的位置不正确。
您可以通过进入“包含文件视图”,并逐个单击每个包含文件,直到找到 Visual Studio 找不到的文件。之后,您可以将该文件添加为现有项,然后删除无法找到的引用即可解决问题。
一个合理的问题是:如果 Visual Studio 不知道包含文件在哪里,它怎么能构建呢?
我们认为,.vcproj 文件在某个地方具有对有问题文件的相对路径,它在 Visual Studio 的 GUI 中没有显示,这就解释了为什么项目实际上会构建,即使包含的树形视图不正确。

4
VC能够构建项目是因为它们是头文件,而头文件实际上不会被编译。只有当任何一个头文件被.C/.CPP文件实际使用时,构建才会失败。因此,依赖项检查器(寻找头文件)会将该项目标记为需要重新构建,但实际的编译器(只忽略头文件列表)可以成功运行。 - AHelps
4
令人难以置信的是,如果您在.vcxproj文件中有对文本文件的陈旧引用(即使它根本不是构建的一部分,即使它存在!),也会发生这种情况!我使用向导生成了一个项目,其中包括一个ReadMe.txt文件,我已从磁盘上删除了该文件,但忘记从vcxproj中删除它。 - DLRdave
我找不到任何无法打开的文件(除了一个,但那个在硬盘上)。它说这种类型的文件无法在Visual Studio 2010 Express SKU上打开,或者类似于此的信息。 - Anonymous Penguin
2
什么是“包含文件视图”,如何进入它? - Ben
1
“Include File View” 可能是解决方案资源管理器中的“包含文件”部分。 - Jaywalker

12

这个被采纳的答案帮助我找到了解决我所面临的烂摊子项目问题的正确路径。然而,我必须处理大量错误的 include 头文件。在详细调试输出的情况下,删除一个头文件会导致 IDE 卡死 30 秒并输出调试信息,这使得整个过程变得非常缓慢。

我变得不耐烦了,写了一个简单粗暴的 Python 脚本来检查(Visual Studio 2010)项目文件,并一次性输出所有缺失的文件及其所在的筛选器。你可以在这里找到它的 Gist:https://gist.github.com/antiuniverse/3825678 (或者这个支持相对路径的分支

例如:

D:\...> check_inc.py sdk/src/game/client/swarm_sdk_client.vcxproj
[Header Files]:
  fx_cs_blood.h   (cstrike\fx_cs_blood.h)
  hud_radar.h   (cstrike\hud_radar.h)
[Game Shared Header Files]:
  basecsgrenade_projectile.h   (..\shared\cstrike\basecsgrenade_projectile.h)
  fx_cs_shared.h   (..\shared\cstrike\fx_cs_shared.h)
  weapon_flashbang.h   (..\shared\cstrike\weapon_flashbang.h)
  weapon_hegrenade.h   (..\shared\cstrike\weapon_hegrenade.h)
  weapon_ifmsteadycam.h   (..\shared\weapon_ifmsteadycam.h)
[Source Files\Swarm\GameUI - Embedded\Base GameUI\Headers]:
  basepaenl.h   (swarm\gameui\basepaenl.h)
  ...

源代码:

#!/c/Python32/python.exe
import sys
import os
import os.path
import xml.etree.ElementTree as ET

ns = '{http://schemas.microsoft.com/developer/msbuild/2003}'

#Works with relative path also
projectFileName = sys.argv[1]

if not os.path.isabs(projectFileName):
   projectFileName = os.path.join(os.getcwd(), projectFileName)

filterTree = ET.parse(projectFileName+".filters")
filterRoot = filterTree.getroot()
filterDict = dict()
missingDict = dict()

for inc in filterRoot.iter(ns+'ClInclude'):
    incFileRel = inc.get('Include')
    incFilter = inc.find(ns+'Filter')
    if incFileRel != None and incFilter != None:
        filterDict[incFileRel] = incFilter.text
        if incFilter.text not in missingDict:
            missingDict[incFilter.text] = []

projTree = ET.parse(projectFileName)
projRoot = projTree.getroot()

for inc in projRoot.iter(ns+'ClInclude'):
    incFileRel = inc.get('Include')
    if incFileRel != None:
        incFile = os.path.abspath(os.path.join(os.path.dirname(projectFileName), incFileRel))
        if not os.path.exists(incFile):
            missingDict[filterDict[incFileRel]].append(incFileRel)

for (missingGroup, missingList) in missingDict.items():
    if len(missingList) > 0:
        print("["+missingGroup+"]:")
        for missing in missingList:
            print("  " + os.path.basename(missing) + "   (" + missing + ")")

修改了你的代码以支持相对路径。随意更新你的 gist 并删除对我的 fork 的链接! - ixe013
这对我非常有效!真是省了我不少时间!谢谢!诊断输出中没有任何提示我出了什么问题,但是您的工具向我展示了! - Ed Bayiates
另一个分支用于枚举目录并在找到的每个vcxproj上调用它 https://gist.github.com/paulsapps/4992d2d460f4ef44538d62c9e875ca78 - paulm

8
我已经从解决方案(和磁盘)中删除了一些cpp和头文件,但仍然存在问题。
问题在于,编译器使用的每个文件都会在您的临时目录中生成一个*.tlog文件。当您删除一个文件时,此*.tlog文件不会更新。这是增量构建使用的文件,用于检查您的项目是否最新。
要么手动编辑此.tlog文件,要么清理您的项目并重新构建。

这就是我的全部!我花了几个小时来修复缺失的包含文件,但仍然过时,日志显示缺失的内容不明确。需要摆脱那些TLOG文件!谢谢! - Ed Bayiates

6

我遇到了类似的问题,但在我的情况下没有文件丢失,而是pdb输出文件的定义中存在错误:我忘记了后缀.pdb(我通过调试记录技巧发现了这个问题)。

为了解决这个问题,我在vxproj文件中更改了以下行:

<ProgramDataBaseFileName>MyName</ProgramDataBaseFileName>

为了

<ProgramDataBaseFileName>MyName.pdb</ProgramDataBaseFileName>

6
我在VS2013(更新5)中遇到了这个问题,有两个原因可能会出现,你可以通过在“工具”->“项目和解决方案”->“生成和运行”下启用“详细”构建输出来找到它们。
1. “强制重新编译所有源文件,因为缺少PDB“...”” 这是由于在编译器选项中禁用调试信息输出(在项目设置下:“C/C++”->“调试信息格式”设为“无”和“链接器”->“生成调试信息”设为“否”)而导致的。如果您将“C/C++”->“程序数据库文件名”保留在默认值(即“$(IntDir)vc$(PlatformToolsetVersion).pdb”),由于一个错误,VS将无法找到该文件(https://connect.microsoft.com/VisualStudio/feedback/details/833494/project-with-debug-information-disabled-always-rebuilds)。 要解决此问题,请将文件名清空为""(空字段)。
2. “由于自上次构建以来命令行发生了更改,强制重建所有源文件。” 这似乎也是一个已知的VS错误(https://connect.microsoft.com/VisualStudio/feedback/details/833943/forcing-rebuild-of-all-source-files-due-to-a-change-in-the-command-line-since-the-last-build),并且在较新的版本中已修复(但不是VS2013)。我不知道有什么解决方法,但如果您知道,请在此处发布。

1
这就是我的问题所在。我的项目中没有任何“不是最新版本”的消息,我们花了很长时间才找到问题所在。另外,将其删除或设置为$(IntDir)$(ProjectName).pdb 对我们有用(确保在调试和发布配置中都进行更改)。 - John Grabanski

4

我不知道是否有其他人遇到了同样的问题,但我的项目属性中的"Configuration Properties" -> C/C++ -> "Debug Information Format"设置为"None"时,将其切换回默认值"Program Database (/Zi)"后,可以停止项目重新编译。


1
+1 这对我也有效,在 Visual Studio 2013 上。具体来说,当我将它切换回“无”时,它也能正常工作。 - user541686

4
另一个简单的解决方案可以在Visual Studio Forum中找到。
更改配置:菜单 工具选项项目和解决方案VC++ 项目设置解决方案资源管理器模式 更改为显示所有文件
然后您就可以在解决方案资源管理器中看到所有文件了。
找到标有黄色图标的文件,并将其从项目中删除。
这就可以了。

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