我在 Visual Studio 2008 Express 中有很多链接器错误,我怀疑这些错误与本问题和 this one 中讨论的问题有关。经过大量调查后,我设法解决了这个问题,并认为分享知识会很有用。
总结一下(我在下面给出更多细节):
链接器错误发生是因为%WindowsSdkDir% 的值设置不正确,因此VS 找不到像kernel32.lib 这样的文件,
错误设置的原因非常简单:PATH 变量中出现了一个空格,就在 %SystemRoot%\system32 条目的前面,
这意味着reg query MSDOS 命令已被有效禁用,
-
此命令用于其中一个 VS 批处理文件中设置变量值;因此,批处理文件最终不是从注册表设置%WindowsSdkDir%(我的所有注册表项都是正确的),而是将其设置为等于默认值%VCINSTALLDIR%\PlatformSDK\,这对我的设置不正确。
李>
显然,就我而言,修复很简单:删除空格!但当然,真正有趣的是通往解决方案的途径……
正如我所说,问题的第一个症状是 VS 给出了令人讨厌的链接器错误。从这些我可以理解VS找不到像kernel32.lib这样的文件。
如果您搜索此内容,您很可能会在this SO question 找到自己。目前投票最多的答案提到了WindowsSdkDir,并建议提问者检查它在 VS 设置中是否正确引用。
我很清楚我的 VS 设置不是问题,因为我已经能够在另一台机器上顺利完成安装。更多关于“WindowsSdkDir”的搜索让我在这里找到了这个 SO 问题,我检查了所有建议的注册表项(这里和其他地方):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6342Node\Microsoft\Microsoft SDKs\Windows
HKEY_CURRENT_USER\SOFTWARE\Wow6342Node\Microsoft\Microsoft SDKs\Windows
所有这些都已正确设置:CurrentInstallFolder 值的注册表值始终为C:\Program Files\Microsoft SDKs\Windows\v6.0A\。我不明白为什么 %WindowsSdkDir% 变量被设置了一个不同的值。
更多的搜索让我找到了this 这样的地方,我觉得已经准备好去了解%WindowsSdkDir% 变量是如何设置的。
我对这个过程的最好理解是:
文件C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat 是最早运行的脚本之一。 (顺便说一句,您右键单击并Edit 以查看其内容)。不难算出call "%~dp0bin\vcvars32.bat"这行被执行了。
%~dp0bin\ 被解释为“当前目录中的bin 目录”,因此下一个去处就是那里。
在那个bin 目录中有预期的vcvars32.bat,它只包含一个命令:"%VS90COMNTOOLS%vsvars32.bat"。
要查看 %VS90COMNTOOLS% 的含义,您可以打开 Visual Studio 命令提示符(可在 VS 部分的“开始”菜单中找到)并输入 echo %VS90COMNTOOLS%。对我来说,它扩展到C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools。
所以我发现自己在文件C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vcvars32.bat。这个文件有一些真实的内容,我能够识别出命令 @call :GetWindowsSdkDir 是动作发生的地方。
-
该函数在同一个文件中定义,向下几行:
:GetWindowsSdkDir
@call :GetWindowsSdkDirHelper HKLM > nul 2>&1
@if errorlevel 1 call :GetWindowsSdkDirHelper HKCU > nul 2>&1
@if errorlevel 1 set WindowsSdkDir=%VCINSTALLDIR%\PlatformSDK\
@exit /B 0
-
这个函数显然依赖于同一个文件中的第二个函数:
:GetWindowsSdkDirHelper
@for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Microsoft\Microsoft SDKs\Windows" /v "CurrentInstallFolder"') DO (
if "%%i"=="CurrentInstallFolder" (
SET "WindowsSdkDir=%%k"
)
)
@if "%WindowsSdkDir%"=="" exit /B 1
@exit /B 0
我们现在差不多了。我能够看到使用reg query 命令实际访问注册表值的方式,并且很好地猜测该命令正在返回错误并进入默认设置。
当我尝试在普通 MSDOS cmd 中调用 reg query 时,我收到一条消息,它无法识别。
当然,此时您查看PATH 变量,我在C:\windows\system32\ 条目中遇到了那个讨厌的小空间。该空间是在之前的编辑中偶然放在那里的,真棒!
后记
在编写此答案的过程中,我偶然发现了this SO 答案,它解释了PATH 变量是问题的根源!仅作记录,该 SO 答案实际上指向博客文章 here
您可以看到:GetWindowsSdkDir 函数的定义,它首先在注册表中查找HKLM 值,如果没有找到它们,它会查找HKCU 值。这表明 Visual Studio 2008 Express 不使用 Wow6432Node 分支中的注册表项。