這幾天終於趁著聽課的空檔,把電腦裝了 VC++ 2012 ,這版的一大特色:整合了 device driver 的開發。很快地試玩了一下它的 project wizard :

結果,很不幸地失敗 ...
1>C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h(10920): fatal error C1003: error count exceeds 100; stopping compilation
再看一下 Error list:
Error 1 error C2220: warning treated as error - no 'object' file generated C:\Program Files (x86)\Windows Kits\8.0\Include\shared\sal.h 2884
Error 4 error C2054: expected '(' to follow '_IRQL_requires_same_' C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h 1897
Error 5 error C2085: 'EXCEPTION_ROUTINE' : not in formal parameter list C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h 1903
Error 6 error C2085: 'EXCEPTION_ROUTINE' : not in formal parameter list C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h 1905
Error 7 error C2143: syntax error : missing ';' before '*' C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h 1905
Error 8 error C2143: syntax error : missing ')' before 'constant' C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h 10384
Error 9 error C2143: syntax error : missing '{' before 'constant' C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h 10384
Error 10 error C2059: syntax error : '<Unknown>' C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h 10384
真的是很 ooxx 。問題都是發生在 sal.h, ntdef.h wdm.h 等等基本的 header files 裡。
這類的問題通常是發生在 include 了錯誤的 header files ,所以回頭檢視 solution property : Project > Properties > Configuration Properties > VC++ Directories 。

include directories 多了很多路徑,其他像是 Executable Directories 、Library Directories 也有一樣的問題。嗯嗯,VC++ 2012 匯入了電腦上其他版本 VC++ 的設定,可能的原因之一:安裝完 2012 、第一次啟動時,我允許了 2012 去找尋舊版本的設定並匯入所導致。再點開 Include Directories 看一下:

發現這些多餘的路徑都是來自 Inherited values 。這裡,我試了兩種解決方式:
- 解法一
取消 Inherit from parent or project defaults ,然後重新把需要的路徑一個一個加回去,也就是手動把
$(ProjectDir)、$(CRT_INC_PATH)、$(ddk_INC_PATH)、$(KIT_SHARED_INC_PATH) 加上去。手動作這件事除了麻煩外,還只能用在這個 project 上,也就是一旦我開了新的 driver solution 或是在當下 solution 下新增新的 driver project 都得重做一次。
- 解法二
比較一勞永逸, VC++ 把這個 Inherited Values 定義在 C:\Users\<user-name>\AppData\Local\Microsoft\MSBuild\v4.0 下的檔案裡頭,檔案是根據不同 configuration 而命名:
Microsoft.Cpp.ARM.user.props
Microsoft.Cpp.Itanium.user.props
Microsoft.Cpp.Win32.user.props
Microsoft.Cpp.x64.user.props
*.props 是 XML 格式,把不用的 path 都清除乾淨,只留下 default value 就可以了。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
<IncludePath>$(IncludePath)</IncludePath>
<ReferencePath>$(ReferencePath)</ReferencePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<SourcePath>$(SourcePath)</SourcePath>
<ExcludePath>$(ExcludePath)</ExcludePath>
</PropertyGroup>
</Project>
這個方法是比較一勞永逸,不過有個大缺點:不同版本的 Visual C++ 會共用這個檔案。像我的電腦修改了後, VC++ 2010 的 VC++ project 的預設值也會受到影響,但已經產生的、既有 project 則不受影響,算是不幸中的大幸。