【问题标题】:Cannot compile with VC++/VS2010 targeting x64: LNK1158: cannot run cvtres.exe无法使用面向 x64 的 VC++/VS2010 进行编译:LNK1158:无法运行 cvtres.exe
【发布时间】:2012-03-17 22:06:21
【问题描述】:

作为一名 C# 开发人员,我最近决定尝试编写一些 C++ 程序,主要是因为我发现了一个有趣的 C++ API,我想尝试一下。前几天写了一个很简单的程序,在x64目标平台上编译,运行起来,一切都很顺利。

然而,昨天我更改了一些代码,试图编译它,但是链接器开始抱怨:

LNK1158:无法运行“cvtres.exe”

由于我是开发 C++ 程序的新手,我想我一定犯了一些初学者的错误。但是,在检查了所有配置、搜索谷歌几个小时并尝试了几个“修复”之后,我开始认为这个问题可能是由更多的委托引起的,关键是:我似乎根本无法解决这个问题,所以我希望在这里得到一些好的反馈。

首先,让我列出我的配置:

  • 我正在运行 Windows 7 (x64) 并且正在使用 VS2010 Premium。
  • 我创建了一个标准的空 Win32 控制台应用程序,其中只有一个包含主要功能的 .cpp 文件。这不是一个 Hello World 程序,但也不远了。
  • 因为我有一个 x64 平台,所以我也在使用 x64 目标平台配置。我创建了这个配置,没有从 Win32 配置中复制任何设置。
  • 在项目属性 -> VC++ 目录中,我将所有目录保留为默认值(尽管我确实更改了几次以尝试解决问题,但均未成功,因此我恢复了默认值)。

最后一点似乎很关键,因为 VC++ 目录设置决定了使用哪个编译器和链接器。此时,使用位于 $(VCInstallDir)bin\x86_amd64 目录中的交叉编译器。此外,所有其他目录似乎都指向所有库的 x64 版本等等。

当你google这个问题时,你会发现使用的链接器(link.exe)要执行cvtres.exe,它找不到。当 cvtres.exe 既不在与链接器相同的目录中,也不在使用 PATH 变量解析的目录中时,似乎会出现此问题。

所以我验证了这一点,在 $(VCInstallDir)bin\x86_amd64 中确实没有 cvtres.exe 的版本(尽管在基目录中有它的版本($( VCInstallDir)bin) 和 'pure' $(VCInstallDir)bin\amd64 目录),PATH 变量也不包含任何包含 cvtres 版本的目录列表。执行。

-- 尝试 #01 - 修复手头的问题--

因此,您可能会断定该错误实际上是合法的错误,我应该通过直接在 $(VCInstallDir)bin\x86_amd64 中复制 cvtres.exe 版本来解决此问题strong> 目录,或者编辑 PATH 变量,使其指向它的可用版本。

很遗憾,这些都不起作用。

当我将 cvtres.exe 从 $(VCInstallDir)bin$(VCInstallDir)bin\amd64 复制到 $(VCInstallDir)bin\x86_amd64 并编译,我要么得到相同的消息(现在指的是确切位置:'cannot run $(VCInstallDir)bin\x86_amd64\cvtres.exe',虽然它在那里)或链接器退出时出现一些未知的错误代码(可能是因为 $(VCInstallDir)bin\amd64 的版本是原生 x64,这与我发现在 WoW64 模式下运行的 x86 交叉编译器不同)。

尝试编辑 PATH 变量以使链接器可以找到版本 cvtres.exe 的问题也失败了,因为我不知道要引用的路径(似乎保留了更多版本的 cvtres.exe在不同的位置,例如在 .NET 4.0 SDK 目录中)。

-- 尝试 #02 - 通过尝试不同的方法来规避问题--

我采取的另一条路径是尝试使用 $(VCInstallDir)bin\amd64 中的编译器和链接器,而不是交叉编译器。毕竟,我运行的是 64 位机器,所以我不需要使用交叉编译器,尽管微软似乎默认选择了这个,不管你的本地配置/操作系统如何。

所以我将 VC++ 目录更改为指向此位置,确实问题不再出现,但现在我遇到了运行 CL.exe 的跟踪器问题:

TRK0002:[CL.exe] '@[TempFile].rsp':句柄无效。

当我寻找这个临时文件时,我找不到它,但我不确定它是在编译“完成”后立即删除还是根本不存在。不幸的是,谷歌搜索这个问题也是一个死胡同,MS Visual Studio 2010 team even recognise this issue but have put it on 'Won't Fix'。简而言之,原生 64 位编译似乎是 VS2010 的一个已知的普遍问题,所以我决定回到这个问题上,特别是因为遇到这个问题的其他人总是说‘好吧,你可以解决这个问题使用交叉编译器而不是原生 x64 编译器。

好的,所以现在我发现自己的选择已经不多了......而且疯狂的是,几天前一切正常,我很确定我没有更改或安装任何关于这个项目的东西,也没有以某种方式更新了 Visual Studio 或 .NET Framework。我什至检查了 Windows 更新,但最近几天找不到任何相关更新。

作为最后的手段,我唯一能做的就是将整个东西降级到 32 位并下载 32 位版本的 API,但我真的很想避免这个,因为它看起来对我来说,我应该能够在我的 64 位笔记本电脑/操作系统上编译和运行 64 位应用程序。

请问有什么建议吗?

更新:根据this instruction from MS,链接器的 PATH 变量必须指向 VC++ 安装的基目录。那就是我一直在说的$(VCInstallDir)bin。我已经尝试过了,但没有解决问题。我想知道当我似乎不知道的 VS Build 被触发时,后台会发生什么......

@Hans Passant:谢谢小费!进程监视器显示 link.exe 正在尝试在以下位置之一查找 cvtres.exe:

  • $(VCInstallDir)bin\x86_amd64
  • $(SourceFileDir)
  • C:\Windows\System32\NV

不用说,这些目录中都不存在 cvtres.exe。 搜索这些位置是相当奇怪的。我至少希望 $(VCInstallDir)bin 被搜索,因为这个目录在 VC++ 目录和 PATH 变量(为此我手动编辑)中都明确列出。我想这归结为找出为什么这种行为是这样的......

Update2:为了提供一些额外的信息,我决定将 cvtres.exe 从 $(VCInstallDir)bin 复制到 $(VCInstallDir) bin\x86_amd64 目录,基于我使用 ProcMon 的发现,只是为了看看当时发生了什么。首先,和以前一样,Visual Studio 告诉我以下内容:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\x64\Microsoft.Cpp.x64.Targets(389,5):错误 MSB6006:“link.exe”以代码 -1073741515 退出。(此处的行仅指检查哪些非零退出代码可接受的设置 - 实际的错误代码由 link.exe 返回。)

但是,在 ProcMon 的输出窗口中,我可以看到 cvtres.exe 已找到并且正在执行大量工作 - 看起来要完成,但我对此不太确定。无论如何,该错误仍然阻止我执行创建的可执行文件,因为它抱怨找不到某个引用的库。这可能是由于链接器没有正确完成,所以简而言之,它并没有解决我的问题。

Update3:我尝试的另一件“有趣”的事情是创建一个新的、普通的 Win32 项目,使用所有 MS 默认值,我什至没有接触为我生成的代码(主要函数立即返回),只是为了看到至少一个程序编译。令人惊讶的是,我现在得到了与上面相同的错误(link.exe 退出,代码为 -1073741515),所以现在我真的开始认为我的安装确实有问题。

然后我尝试卸载并重新安装 Visual Studio 的 VC++ 部分,但无济于事...此时,无法选择完整安装 Visual Studio,因为我还在开发 C#项目,并且我安装了大量其他加载项,这些加载项目前占用了我太多时间来重新安装和重新配置。如果在那之前没有任何结果,我可能会在周末尝试这个。

相反,我对错误代码进行了一些研究,我认为这与 link.exe 无法找到或访问它所需的依赖项有关。为了安全起见,我已经关闭了 VirusScanner(没有帮助),所以现在我正在下载最新的 Windows SDK (7.1) 以查看是否有任何作用。如果这没有帮助,我猜它要么是一个可怕的错误,要么我的安装真的在某个地方搞砸了,我可能不得不重新安装 VS 和所有它的东西......

还是谢谢你的建议!

【问题讨论】:

  • 使用 sysinternal 的 procmon 实用程序查看正在搜索 .exe 的链接器
  • 我有一个类似的设置(VS Pro,不是高级版),我看到link.exe 试图在$(VCInstallDir)bin\x86_amd64 中找到cvtres.exe,然后是$(SourceFileDir),但后来它在@ 中找到它987654327@ 并成功完成。我尝试将cvtres.exe 移动到x86_amd64 文件夹以查看它是否失败并且没有。也许需要全新安装 VS?

标签: visual-studio-2010 visual-c++ compiler-construction linker 64-bit


【解决方案1】:

C:\Windows\System32\NV 路径可能指向在herehere 讨论的问题。

似乎某些可以切换图形模式(集成/离散)的 NVIDIA 驱动程序在某些情况下会损坏系统路径(例如,系统路径上有 Intel 无线路径)。

禁用 NV Services 服务可能会解决您的问题。

【讨论】:

  • Jorik,非常感谢您:您提到的 nVidia/Intel 驱动程序损坏了我的环境变量,导致 link.exe 无法再成功执行。我刚刚开始了一个新线程,现在我取消了这个线程,以解释我已经得出结论,链接器必须使用错误的 PATH(以及可能的其他)变量执行,但为什么仍然是个谜。
【解决方案2】:

重现此错误的一种简单方法如下:

打开命令提示符 (cmd.exe),输入:

> powershell

在 Power Shell 中,键入:

> echo ${Env:PATH}

如果输出如下所示:

C:\Windows\system32\NV;.;

那么你有这个错误。

【讨论】:

    【解决方案3】:

    我刚刚在我的 VS2010 (SDK7.1) 解决方案中找到了一个(总共 3 个)项目(项目链接在顺序线性依赖链中),项目文件中有一个 .rc 文件是空的. 删除空的 .rc 文件(从项目中,不删除它)解决了“致命错误 LNK1158: ... cvtres.exe”问题。

    更新:将工作版本的 cvtres.exe 复制到正确的位置,以便 MSBuild 可以获取它:

    xcopy "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cvtres.exe" "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\"
    

    【讨论】:

      【解决方案4】:

      我一直得到异常

      Microsoft.Cpp.x64.Targets(152,5):错误 MSB6006:“CL.exe”以代码 1 退出。

      因为我用的是MFC项目,然后转成CLR/CLI项目,最后发现是targetver.h文件的原因。

      我删除它后,项目构建良好。此外,项目在Release/Debug/Win32和Debug/x64下构建良好,只有x64版本才有这个问题。

      【讨论】:

        【解决方案5】:

        我在 Nvidia 的 4200m 卡上运行,它改变了我的路径。禁用 NV 服务没有帮助。然后我从 Nvidia 的网站安装了新的驱动程序 310.90,它解决了这个问题。请注意,当我安装驱动程序时,我选中了“执行全新安装”框。

        【讨论】:

          【解决方案6】:

          我在 VMWare 11 (Win XP 32) 上运行 VS6 时遇到了同样的问题。

          我不得不从 'msconfig -> services' 禁用 .NET 服务

          干杯

          【讨论】:

            猜你喜欢
            • 2019-08-25
            • 2016-05-14
            • 2014-01-27
            • 1970-01-01
            • 2011-07-02
            • 2015-08-23
            • 2012-05-23
            • 2012-11-06
            • 1970-01-01
            相关资源
            最近更新 更多