Reputation: 91835
I'm attempting to build some C++ code that requires the Windows 7.0 SDK header files and libraries. My VC++ Directories is set to:
$(VCInstallDir)include
$(VCInstallDir)atlmfc\include
$(WindowsSdkDir)\include
$(WindowsSdkDir)\common\include
$(FrameworkSDKDir)include
My $(WindowsSdkDir)
variable should be set to C:\Program Files\Microsoft SDKs\Windows\v7.0\
-- I've used the SDK's "Visual Studio Registration" configuration tool to set it, and it looks correct in the registry. I've checked under HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows
(and the same in Wow6432Node
.
Despite this, Visual C++ is still picking up header files from C:\Program Files\Microsoft SDKs\Windows\v6.0A\
What's wrong, and how do I fix it?
Upvotes: 17
Views: 31259
Reputation: 1646
I had a lot of linker errors in Visual Studio 2008 Express which I suspected were related to the issues being discussed in this question and this one. After a lot of investigating I managed to fix the problem, and thought it would be useful to share the knowledge.
In summary (I give more detail below):
the linker errors were happening because the value of %WindowsSdkDir%
was not being set correctly, and therefore VS could not find files like kernel32.lib
,
the reason for the incorrect setting was frustratingly simple: a space had crept into the PATH
variable just at the front of the %SystemRoot%\system32
entry,
this meant that the reg query
MSDOS command had effectively been disabled,
this command is used in one of the VS batch files to set variable values; the batch file therefore ended up setting %WindowsSdkDir%
not from the registry (all my registry entries were correct), but instead set it to equal its default value of %VCINSTALLDIR%\PlatformSDK\
which was not correct for my setup.
Obviously, the fix was easy in my case: remove the space! But of course, it is the route to the solution that really is the interesting bit...
As I said, the first symptom of the problem was that VS was giving nasty linker errors. I was able to understand from these that VS was not able to find files like kernel32.lib
.
If you search around this you are likely to find yourself at this SO question. The answer that currently sits with the most votes mentions WindowsSdkDir
, and suggests that the questioner check it is correctly referenced in the VS settings.
It was clear to me that my VS settings were not the problem because I had already been able to get my installation completed error free on another machine. More searching on 'WindowsSdkDir' led me to this here SO question, and I checked all the registry entries that are suggested (here and elsewhere):
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
All of these were correctly set: the value in the registry of the CurrentInstallFolder
value was always C:\Program Files\Microsoft SDKs\Windows\v6.0A\
. I was at a loss to understand why the %WindowsSdkDir%
variable was being set with a yet different value.
Yet more searching led me to places like this, and I felt ready to have a go at understanding how the %WindowsSdkDir%
variable gets set.
My best understanding of the process is:
The file C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat
is the one of the first scripts to get run. (BTW you right-click and Edit
to see its contents). It was not difficult to work out that the line call "%~dp0bin\vcvars32.bat"
is executed.
The %~dp0bin\
is interpreted as 'the bin
directory in the current directory`, and therefore the next place to go is there.
In that bin
directory there is the expected vcvars32.bat
, and it contains only one command: "%VS90COMNTOOLS%vsvars32.bat"
.
To see what %VS90COMNTOOLS%
means you can open the Visual Studio command prompt (which you find in the Start Menu in the VS section) and enter echo %VS90COMNTOOLS%
. For me it expands to C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools
.
So I find myself at the file C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vcvars32.bat
. This file has some real content, and I was able to recognize that the command @call :GetWindowsSdkDir
is where the action happens.
That function is defined in this same file, a few lines down:
: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
This function obviously depends on a second function in that same file:
: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
We are nearly there now. I was able to see how the registry values are actually accessed with the reg query
command, and it was a good guess that the command was returning errors and falling through to the default setting.
When I tried calling reg query
in a vanilla MSDOS cmd
I got a message that it was not recognized.
Naturally you go look in the PATH
variable at this point, and there I came across that nasty little space in the C:\windows\system32\
entry. The space had been put there by accident on a previous edit, fancy that!
Postscript
In the process of writing this answer I stumbled across this SO answer which explains how it is the PATH
variable that is the source of the problem! Just for the record, that SO answer actually points to a blog post here
You can see form the definition of the :GetWindowsSdkDir
function that it looks in the registry at the HKLM
values first, and if it does not find them it looks at the HKCU
values. This suggests to me that Visual Studio 2008 Express does not use the registry entries in the Wow6432Node
branches.
Upvotes: 3
Reputation: 480
Just follow the brief below:
start-> run-> type in: regedit now go to: HKEY_LOCAL_MACHINE -> SOFTWARE->Wow6432Node -> Microsoft ->Microsoft SDKs->Windows ->v8.0
Now on the right pane right click and New String Value as WindowsSDKDir. As its value type in:
C:\Program Files\Windows Kits\8.0\
That's it now build your solution again. N.B. 8.0 version is of mine you will find there yours.
Upvotes: 0
Reputation: 81
I came across this same problem and found a solution which seems better than hacking around with the registry...
"Open any project and change the Platform Toolset to Windows7.1SDK and build it. After this, the macro $(WindowsSdkDir) changes for all projects to v7.1 regardless of the selected Platform Toolset."
It worked for me.
Upvotes: 8
Reputation: 1253
If the blog post doesn't work. Try running the vsvars32.bat in your <VS installdir>/Common7/Tools/vsvars32.bat
and then run devenv.exe (in the same environment).
Upvotes: 0
Reputation: 91835
Ah. Found this blog post: http://blogs.msdn.com/windowssdk/archive/2008/06/30/winsdk-bug-notification-sdk-config-tool-appears-to-work-but-fails.aspx
Essentially, the configuration tool only updates the HKEY_LOCAL_MACHINE settings; Visual Studio uses the HKEY_CURRENT_USER settings in preference.
Upvotes: 17