共用方式為


Visual Studio C++ Project 系統擴充性和工具組整合

Visual C++ 專案系統用於.vcxproj檔案。 它以 Visual Studio Common Project System (CPS) 為基礎,並提供額外的、C++特定擴充點,以便輕鬆整合新的工具組、建置架構和目標平臺。

C++ MSBuild 目標結構

所有.vcxproj檔案都會匯入這些檔案:

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

這些檔案本身意義不大。 相反地,它們會根據這些屬性值匯入其他檔案:

  • $(ApplicationType)

    範例:Windows 市集、Android、Linux

  • $(ApplicationTypeRevision)

    這必須是符合格式的有效版本字串,格式為主要.次要[.build[.revision]]。

    範例:1.0、10.0.0.0

  • $(Platform)

    基於歷史原因,名為 「Platform」 的組建架構。

    範例:Win32、x86、x64、ARM

  • $(PlatformToolset)

    範例:v140、v141、v141_xp、llvm

這些屬性值會指定 $(VCTargetsPath) 根資料夾底下的資料夾名稱:

$(VCTargetsPath)\
     應用程式類型\
        $(ApplicationType)\
            $(ApplicationTypeRevision)\
                 平臺\
                    $(Platform)\
                         PlatformToolsets\
                            $(PlatformToolset)
     平臺\
        $(Platform)\
             平台工具集\
                $(PlatformToolset)

當 Windows Desktop 專案的 $(ApplicationType) 為空時,將使用 $(VCTargetsPath)\平台\ 資料夾。

新增平臺工具組

若要新增新的工具組,例如現有 Win32 平臺的 “MyToolset”,請在 $(VCTargetsPath)\Platform\Win32\PlatformToolsets\下建立 MyToolset 資料夾,並在其中建立 Toolset.propsToolset.targets 檔案。

PlatformToolsets 底下的每個資料夾名稱 會出現在 [項目屬性] 對話框中,作為指定平臺的可用 Platform Toolset,如下所示:

專案 [屬性頁] 對話方塊中的 [平台工具集] 屬性

建立類似的 MyToolset 資料夾和 Toolset.propsToolset.targets 工具組支援的每個現有平台資料夾中的檔案。

新增平臺

若要新增新的平臺,例如 「MyPlatform」,請在 $(VCTargetsPath)\Platform\下建立 MyPlatform 資料夾,並在其中建立 Platform.default.propsPlatform.props,以及 Platform.targets 檔案。 同時建立 $(VCTargetsPath)\Platforms\MyPlatform\PlatformToolsets\ 資料夾,並在其中建立至少一個工具組。

每個 $(ApplicationType)$(ApplicationTypeRevision) 資料夾中 Platforms 資料夾下的所有資料夾名稱,皆會顯示在 IDE 中,作為專案的可用 平臺 選擇。

[新增專案平臺] 對話框中的新平台選擇

新增應用程式類型

若要新增應用程式類型,請在 $(VCTargetsPath)\Application Type\ 下建立 MyApplicationType 資料夾,並在其中建立 Defaults.props 檔案。 應用程式類型至少需要一個修訂,因此也請建立 $(VCTargetsPath)\Application Type\MyApplicationType\1.0 資料夾,並在其中建立 Defaults.props 檔案。 您也應該建立 $(VCTargetsPath)\ApplicationType\MyApplicationType\1.0\Platforms 資料夾,並在其中建立至少一個平臺。

用戶介面中看不到 $(ApplicationType)$(ApplicationTypeRevision) 屬性。 這些專案定義於專案範本中,且在建立專案之後無法變更。

.vcxproj匯入樹狀結構

Microsoft C++屬性和目標檔案匯入的簡化樹狀結構看起來如下:

$(VCTargetsPath) \ Microsoft.Cpp.Default.props
     $(MSBuildExtensionsPath) \ $(MSBuildToolsVersion) \ Microsoft.Common.props
     $(VCTargetsPath) \ ImportBefore\Default\*。屬性
     $(VCTargetsPath) \ 應用程式類型\$(ApplicationType)\Default.props
     $(VCTargetsPath) \ 應用程式類型\$(ApplicationType)\$(ApplicationTypeRevision)\預設.props
     $(VCTargetsPath) \ 應用類型\$(ApplicationType)\$(ApplicationTypeRevision)\平台\$(Platform)\Platform.default.props
     $(VCTargetsPath) \ ImportAfter\預設\*。道具

Windows 桌面專案不會定義 $(ApplicationType),因此只會匯入

$(VCTargetsPath) \ Microsoft.Cpp.Default.props
     $(MSBuildExtensionsPath) \ $(MSBuildToolsVersion) \ Microsoft.Common.props
     $(VCTargetsPath) \ ImportBefore\Default\*。道具
     $(VCTargetsPath) \ Platform\$(Platform)\Platform.default.props
     $(VCTargetsPath) \ ImportAfter\預設\*。道具

我們將使用 $(_PlatformFolder) 屬性來保存 $(Platform) 平台資料夾位置。 此屬性為

$(VCTargetsPath) \ 平臺\$(Platform)

適用於 Windows 傳統型應用程式 和

$(VCTargetsPath) \ 應用程式類型\$(ApplicationType)\$(ApplicationTypeRevision)\平臺\$(Platform)

對於其他一切。

屬性檔案會以以下順序匯入:

$(VCTargetsPath) \ Microsoft.Cpp.props
     $(_PlatformFolder) \ Platform.props
         $(VCTargetsPath) \ Microsoft.Cpp.Platform.props
             $(_PlatformFolder) \ ImportBefore\*。道具
             $(_PlatformFolder) \ PlatformToolsets\$(PlatformToolset)\Toolset.props
             $(_PlatformFolder) \ ImportAfter\*。道具

目標檔案會依下列順序匯入:

$(VCTargetsPath) \ Microsoft.Cpp.targets
     $(VCTargetsPath) \ Microsoft.Cpp.Current.targets
         $(_PlatformFolder) \ Platform.targets
             $(VCTargetsPath) \ Microsoft.Cpp.Platform.targets
                 $(_PlatformFolder) \ ImportBefore\*。目標
                 $(_PlatformFolder) \ PlatformToolsets\$(PlatformToolset)\Toolset.target
                 $(_PlatformFolder) \ ImportAfter\*。目標

如果您需要為工具組定義一些默認屬性,您可以將檔案新增至適當的 ImportBefore 和 ImportAfter 資料夾。

撰寫 Toolset.props 和 Toolset.targets 檔案

Toolset.propsToolset.targets 檔案完全控制使用此工具組時建置期間會發生什麼情況。 它們也可以控制可用的調試程式、某些 IDE 使用者介面,例如 [屬性頁] 對話框中的內容,以及專案行為的一些其他層面。

雖然工具組可以覆寫整個建置程式,但您通常只想要工具組修改或新增一些建置步驟,或使用不同的建置工具,做為現有建置程式的一部分。 若要達成此目標,工具組可以匯入的一些常見道具和目標檔案。 根據您要工具組執行的動作,這些檔案在匯入或範例中使用可能很有用:

  • $(VCTargetsPath) \ Microsoft.CppCommon.targets

    此檔案會定義原生建置程式的主要部分,也會匯入:

    • $(VCTargetsPath) \ Microsoft.CppBuild.targets

    • $(VCTargetsPath) \ Microsoft.BuildSteps.targets

    • $(MSBuildToolsPath) \ Microsoft.Common.Targets

  • $(VCTargetsPath) \ Microsoft.Cpp.Common.props

    為使用Microsoft編譯程式和目標 Windows 的工具組設定預設值。

  • $(VCTargetsPath) \ Microsoft.Cpp.WindowsSDK.props

    此檔案會決定 Windows SDK 位置,並為以 Windows 為目標的應用程式定義一些重要屬性。

整合工具組特定的目標與預設C++建置程式

默認C++建置程式定義於 Microsoft.CppCommon.targets中。 這些設定目標不呼叫任何特定的建置工具,它們會指定主要建置步驟,其順序和相互依賴性。

C++組建有三個主要步驟,由下列目標表示:

  • BuildGenerateSources

  • BuildCompile

  • BuildLink

因為每個建置步驟都可以獨立執行,因此在單一步驟中執行的目標不能依賴以不同步驟一部分執行的目標中所定義的專案群組和屬性。 此部門允許特定組建效能優化。 雖然它並非預設使用,但仍建議您尊重此區分。

在每個步驟內執行的目標是由這些屬性所控制:

  • $(BuildGenerateSourcesTargets)

  • $(BuildCompileTargets)

  • $(BeforeBuildLinkTargets)

每個步驟也有 Before 和 After 屬性。

<Target
  Name="_BuildGenerateSourcesAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildGenerateSourcesTargets);$(BuildGenerateSourcesTargets);$(AfterBuildGenerateSourcesTargets)" />

<Target
  Name="\_BuildCompileAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildCompileTargets);$(BuildCompileTargets);$(AfterBuildCompileTargets)" />

<Target
  Name="\_BuildLinkAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildLinkTargets);$(BuildLinkTargets);$(AfterBuildLinkTargets)" />

如需每個步驟中包含的目標範例,請參閱 Microsoft.CppBuild.targets 檔案:

<BuildCompileTargets Condition="'$(ConfigurationType)'\!='Utility'">
  $(BuildCompileTargets);
  _ClCompile;
  _ResGen;
  _ResourceCompile;
  $(BuildLibTargets);
</BuildCompileTargets>

如果您查看目標,例如 _ClCompile,您會看到它們不會自行執行任何動作,而是依賴其他目標,包括 ClCompile

<Target Name="_ClCompile"
  DependsOnTargets="$(BeforeClCompileTargets);$(ComputeCompileInputsTargets);MakeDirsForCl;ClCompile;$(AfterClCompileTargets)" >
</Target>

ClCompile 和其他建置工具特定目標會在 Microsoft.CppBuild.targets中定義為空白目標:

<Target Name="ClCompile"/>

因為 ClCompile 目標是空的,除非工具集覆寫該目標,否則不會執行實際的建置動作。 工具組目標可以覆寫 ClCompile 目標,也就是說,在匯入 Microsoft.CppBuild.targets之後,它們可以包含另一個 ClCompile 定義:

<Target Name="ClCompile"
  Condition="'@(ClCompile)' != ''"
  DependsOnTargets="SelectClCompile">
  <!-- call some MSBuild tasks -->
</Target>

儘管其名稱是於 Visual Studio 實現跨平台支援之前創建的,但 ClCompile 目標不需要呼叫 CL.exe。 它也可以使用適當的 MSBuild 工作來呼叫 Clang、gcc 或其他編譯程式。

除了 SelectClCompile 目標以外,ClCompile 目標不應該有任何相依性,這是單一檔案編譯命令在 IDE 中運作的必要專案。

用於工具集目標的 MSBuild 工作

若要叫用實際的建置工具,目標必須呼叫 MSBuild 工作。 有一個基本的 Exec 任務,允許您指定要執行的命令列。 不過,建置工具通常有許多選項、輸入和輸出來追蹤累加建置,因此對它們有特殊工作更有意義。 例如,CL 工作會將 MSBuild 屬性轉譯成 CL.exe 參數、將它們寫入回應檔,以及呼叫 CL.exe。 它也會追蹤所有輸入和輸出檔案,以供後續的累加組建使用。 如需詳細資訊,請參閱 累加組建和 up-to日期檢查

Microsoft.Cpp.Common.Tasks.dll 會執行下列工作:

  • BSCMake

  • CL

  • ClangCompile (clang-gcc 選項)

  • LIB

  • LINK

  • MIDL

  • Mt

  • RC

  • XDCMake

  • CustomBuild (例如 Exec,但具有輸入和輸出追蹤)

  • SetEnv

  • GetOutOfDateItems

如果您有一個工具可以執行與現有工具相同的動作,且具有類似的命令列參數(如 clang-cl 與 CL),那麼您可以對它們兩者使用相同的工作。

如果您需要為建置工具建立新工作,您可以從下列選項中選擇:

  1. 如果您很少使用此任務,或是幾秒鐘對於您的組建無關緊要,您可以使用 MSBuild「內嵌」任務:

    • Xaml 工作 (自訂建置規則)

      如需 Xaml 工作宣告的其中一個範例,請參閱 $(VCTargetsPath)\BuildCustomizations\masm.xml,如需其用法,請參閱 $(VCTargetsPath)\BuildCustomizations\masm.targets

    • 編碼任務

  2. 如果您想要更好的任務效能,或需要更複雜的功能,請使用MSBuild 的一般任務編寫流程。

    如果工具命令行上未列出此工具的所有輸入和輸出,如 CLMIDLRC 案例一樣,如果您想要自動輸入和輸出檔案追蹤和 .tlog 檔案建立,請從 Microsoft.Build.CPPTasks.TrackedVCToolTask 類別衍生您的工作。 目前,雖然基底 ToolTask 類別有檔,但 TrackedVCToolTask 類別的詳細數據沒有範例或檔。 如果這會特別感興趣,請在 Developer Community上將您的語音新增至要求。

增量建置和 up-to日期檢查

預設 MSBuild 累加建置目標會使用 InputsOutputs 屬性。 如果您指定它們,MSBuild 只有在任一輸入的時間戳比所有輸出的時間戳更新時,才會呼叫目標。 因為原始程式檔通常會包含或匯入其他檔案,而建置工具會根據工具選項產生不同的輸出,所以很難在 MSBuild 目標中指定所有可能的輸入和輸出。

若要管理此問題,C++組建會使用不同的技術來支援累加組建。 大部分的目標不會指定輸入和輸出,因此一律會在建置期間執行。 目標所呼叫的工作會將所有輸入和輸出的相關信息寫入 tlog 擴展名為 .tlog 的檔案。 之後的構建會使用 .tlog 檔案來檢查哪些變更,以及哪些需要重建,還有 up-to-date。 .tlog 檔案也是 IDE 中預設組建 up-to日期檢查的唯一來源。

若要判斷所有輸入和輸出,原生工具工作會使用 msBuild 所提供的 tracker.exe 和 FileTracker 類別。

Microsoft.Build.CPPTasks.Common.dll 定義公用抽象基類 TrackedVCToolTask。 大部分原生工具工作都是衍生自這個類別。

從 Visual Studio 2017 update 15.8 開始,您可以使用 Microsoft.Cpp.Common.Tasks.dll 中實作的 GetOutOfDateItems 工作,針對具有已知輸入和輸出的自定義目標產生 .tlog 檔案。 或者,您可以通過使用 WriteLinesToFile 任務來建立它們。 如需範例,請參閱 $(VCTargetsPath)\BuildCustomizations\masm.targets 中的 _WriteMasmTlogs 目標。

.tlog 檔案

.tlog 檔案有三種類型:讀取寫入,以及 命令行。 讀取和寫入 .tlog 檔案被累加組建和 IDE 中的 up-to-date 檢查所使用。 命令行 .tlog 檔案只會用於累加組建中。

MSBuild 提供這些協助程式類別來讀取和寫入 .tlog 檔案:

FlatTrackingData 類別可用於存取 .tlog 檔案,無論是讀取或寫入,並識別哪些輸入比輸出更新,或者檢查是否有輸出遺漏。 它用於 up-to-date 檢查中。

命令行 .tlog 檔案包含組建中使用的命令行相關信息。 它們只會用於累加組建,而不是 up-to日期檢查,因此內部格式是由產生它們的 MSBuild 工作所決定。

讀取 .tlog 格式

讀取 .tlog 檔案(*.read.*.tlog)包含來源檔案及其相依性的相關資訊。

行開頭的脫字符號(^)表示一個或多個來源。 共用相同相依性的來源會以垂直線分隔(|)。

相依性檔案會列在來源後面,每一個都列在自己的行上。 所有檔名都是完整的檔案路徑。

例如,假設您在 F:\test\ConsoleApplication1\ConsoleApplication1中找到您的專案來源。 如果您的原始程式檔 Class1.cpp,則包含下列專案:

#include "stdafx.h" //precompiled header
#include "Class1.h"

然後,CL.read.1.tlog 檔案包含來源檔案,後面接著其兩個相依性:

^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.CPP
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PCH
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.H

不需要以大寫撰寫檔名,但對於某些工具來說,這是一種便利性。

寫入 .tlog 格式

Write .tlog (*.write.*.tlog) 檔案會連接來源和輸出。

行開頭的脫字符(^)表示一個或多個來源。 多個來源會以垂直線分隔(|)。

從來源建置的輸出檔案應該列在來源之後,每個檔案都位於自己的行上。 所有檔名都必須是完整路徑。

例如,對於具有其他原始程序檔 Class1.cpp的簡單 ConsoleApplication 專案,link.write.1.tlog 檔案可能包含:

^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CLASS1.OBJ|F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.OBJ|F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\STDAFX.OBJ
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.ILK
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.EXE
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PDB

設計時期構建

在 IDE 中,.vcxproj專案會使用一組 MSBuild 目標,從專案取得其他資訊,以及重新產生輸出檔。 其中有些目標僅用於設計時建置,但許多目標同時用於一般建置和設計時建置。

如需有關設計時期建置的一般資訊,請參閱 CPS 文件,以取得 設計時間組建。 本檔僅部分適用於 Visual C++ 專案。

設計時間組建檔中提及的 CompileDesignTimeCompile 目標永遠不會針對 .vcxproj 項目執行。 Visual C++ .vcxproj專案使用不同的設計時間目標來取得 IntelliSense 資訊。

IntelliSense 資訊的設計時間目標

.vcxproj專案中所使用的設計時間目標定義於 $(VCTargetsPath)\Microsoft.Cpp.DesignTime.targets中。

GetClCommandLines 目標會收集 IntelliSense 的編譯程式選項:

<Target
  Name="GetClCommandLines"
  Returns="@(ClCommandLines)"
  DependsOnTargets="$(DesignTimeBuildInitTargets);$(ComputeCompileInputsTargets)">
  • DesignTimeBuildInitTargets – 設計時間唯一目標,設計時間建置初始化所需的目標。 除此之外,這些目標會停用一些一般建置功能來改善效能。

  • ComputeCompileInputsTargets – 一組修改編譯程式選項和項目的目標。 這些目標會在設計階段和一般建置中執行。

目標會呼叫 CLCommandLine 工作,以建立用於 IntelliSense 的命令行。 同樣地,儘管它的名稱,它不僅可以處理CL選項,還可以處理Clang和 gcc 選項。 編譯器開關的類型是由 ClangMode 屬性所控制。

目前,CLCommandLine 工作所產生的命令列一律會使用CL開關(即使在 Clang 模式中),因為它們更容易讓 IntelliSense 引擎來解析。

如果您要新增在編譯之前執行的目標,不論是常規還是設計時期,請確保它不會中斷設計時期建置或影響效能。 測試目標最簡單的方式是開啟開發人員命令提示字元並執行此命令:

msbuild /p:SolutionDir=*solution-directory-with-trailing-backslash*;Configuration=Debug;Platform=Win32;BuildingInsideVisualStudio=true;DesignTimebuild=true /t:\_PerfIntellisenseInfo /v:d /fl /fileloggerparameters:PerformanceSummary \*.vcxproj

此命令會產生詳細的組建記錄檔,msbuild.log,其最後具有目標和工作的效能摘要。

請務必在所有作業中使用 Condition ="'$(DesignTimeBuild)' != 'true'",這些作業僅適用於一般組建,而非設計時期的組建。

產生來源的設計時間目標

預設會針對桌面原生專案停用這項功能,目前不支援快取專案

如果已為專案專案定義 GeneratorTarget 元數據,則會在載入專案和變更來源檔案時,自動執行目標。

例如,若要從 .xaml 檔案自動產生.cpp或 .h 檔案,$(VSInstallDir)\MSBuild\Microsoft\WindowsXaml\v16.0\*\Microsoft.Windows.UI.Xaml.CPP.Targets 檔案會定義這些實體:

<ItemDefinitionGroup>
  <Page>
    <GeneratorTarget>DesignTimeMarkupCompilation</GeneratorTarget>
  </Page>
  <ApplicationDefinition>
    <GeneratorTarget>DesignTimeMarkupCompilation</GeneratorTarget>
  </ApplicationDefinition>
</ItemDefinitionGroup>
<Target Name="DesignTimeMarkupCompilation">
  <!-- BuildingProject is used in Managed builds (always true in Native) -->
  <!-- DesignTimeBuild is used in Native builds (always false in Managed) -->
  <CallTarget Condition="'$(BuildingProject)' != 'true' Or $(DesignTimeBuild) == 'true'" Targets="DesignTimeMarkupCompilationCT" />
</Target>

若要使用 Task.HostObject 取得來源檔案的未儲存內容,目標與工作應該註冊為 pkgdef 中指定專案的 MsbuildHostObjects

\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\]
\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\\DesignTimeMarkupCompilationCT;CompileXaml\]
@="{83046B3F-8984-444B-A5D2-8029DEE2DB70}"

Visual Studio IDE 中的 Visual C++專案擴充性

Visual C++ 項目系統是以 VS Project System為基礎,並使用其擴充點。 不過,專案階層實作專屬於Visual C++,而不是以CPS為基礎,因此階層擴充性僅限於項目專案。

專案屬性頁面

如需一般設計資訊,請參閱 VC++ 專案的框架多重目標設定

簡單來說,您在C++專案的 [項目屬性] 對話框中看到的屬性頁是由 規則 檔案所定義。 規則檔會指定要在屬性頁面上顯示的屬性集,以及它們應該儲存在項目檔中的方式和位置。 .xml檔案是使用Xaml格式的規則檔案。 用於序列化的型別在 Microsoft.Build.Framework.XamlTypes中描述。 如需在專案中使用規則檔的詳細資訊,請參閱 屬性頁 XML 規則檔

規則檔案必須新增至 PropertyPageSchema 專案群組:

<ItemGroup>
  <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general.xml;"/>
  <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general_file.xml">
    <Context>File</Context>
  </PropertyPageSchema>
</ItemGroup>

Context 元數據會限制規則可見性,規則類型也會控制,而且可以有下列其中一個值:

Project | File | PropertySheet

CPS 支援內容類型的其他值,但它們不會用於Visual C++ 專案中。

如果規則應該顯示在多個內容中,請使用分號 (;) 來分隔內容值,如下所示:

<PropertyPageSchema Include="$(MyFolder)\MyRule.xml">
  <Context>Project;PropertySheet</Context>
</PropertyPageSchema>

規則格式和主要類型

規則格式很簡單,因此本節只會描述影響規則在使用者介面中外觀的屬性。

<Rule
  Name="ConfigurationGeneral"
  DisplayName="General"
  PageTemplate="generic"
  Description="General"
  xmlns="http://schemas.microsoft.com/build/2009/properties">

PageTemplate 屬性會定義如何在 [屬性頁] 對話框中顯示規則。 屬性可以有下列其中一個值:

屬性 描述
generic 所有屬性都會顯示在類別標題下的一個頁面上
ProjectPropertySheet 情境下可以看見規則,但在 File中看不見。

範例:$(VCTargetsPath)\1033\general.xml
tool 類別會顯示為子頁面。
規則可以在所有內容中顯示:ProjectPropertySheetFile
只有在專案具有定義於 Rule.DataSourceItemType 的專案時,才會在 [項目屬性] 中顯示規則,除非規則名稱包含在 ProjectTools 專案群組中。

範例:$(VCTargetsPath)\1033\clang.xml
debugger 頁面會顯示為偵錯頁面的一部分。
目前會忽略類別。
規則名稱應該符合偵錯啟動器MEF物件的 ExportDebugger 屬性。

範例:$(VCTargetsPath)\1033\debugger_local_windows.xml
自定義 自定義範本。 範本的名稱應該符合 PropertyPageUIFactoryProvider MEF 物件的 ExportPropertyPageUIFactoryProvider 屬性。 請參閱 Microsoft.VisualStudio.ProjectSystem.Designers.Properties.IPropertyPageUIFactoryProvider

範例:$(VCTargetsPath)\1033\userMacros.xml

如果規則使用其中一個以屬性方格為基礎的範本,它可以針對其屬性使用這些擴充點:

擴充規則

如果您要使用現有的規則,但只需要新增或移除幾個屬性,您可以建立 擴充規則

覆寫規則

也許您希望工具組使用大部分專案默認規則,但只取代其中一個或一些規則。 例如,假設您只想要變更 C/C++ 規則以顯示不同的編譯程式參數。 您可以提供與現有規則相同的名稱和顯示名稱的新規則,並在匯入預設 cpp 目標之後,將其包含在 PropertyPageSchema 專案群組中。 專案中只會使用具有指定名稱的一個規則,最後一個包含在 PropertyPageSchema 專案群組中的規則會獲勝。

專案項目

ProjectItemsSchema.xml 檔案會定義將項目視為專案項目的 ContentTypeItemType 值,並定義 FileExtension 元素以決定新檔案要加入哪一項目群組。

默認 ProjectItemsSchema 檔案位於 $(VCTargetsPath)\1033\ProjectItemsSchema.xml中。 若要擴充它,您必須建立具有新名稱的架構檔案,例如 MyProjectItemsSchema.xml

<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">

  <ItemType Name="MyItemType" DisplayName="C/C++ compiler"/>

  <ContentType
    Name="MyItems"
    DisplayName="My items"
    ItemType=" MyItemType ">
  </ContentType>

  <FileExtension Name=".abc" ContentType=" MyItems"/>

</ProjectSchemaDefinitions>

然後在目標檔案中,新增:

<ItemGroup>
  <PropertyPageSchema Include="MyProjectItemsSchema.xml"/>
</ItemGroup>

範例:$(VCTargetsPath)\BuildCustomizations\masm.xml

偵錯器

Visual Studio 中的偵錯服務支援偵錯引擎的擴充性。 如需詳細資訊,請參閱下列範例:

若要指定偵錯會話的偵錯引擎和其他屬性,您必須實作 偵錯啟動器 MEF 元件,並新增 debugger 規則。 如需範例,請參閱 $(VCTargetsPath)\1033\debugger_local_windows.xml 檔案。

部署

.vcxproj專案會針對 部署提供者使用 Visual Studio 專案系統擴充性。

組建 up-To-日期檢查

根據預設,組建 up-to-date 檢查需要讀取 .tlog 並寫入 .tlog 檔案,才能在建置期間於 $(TlogLocation) 資料夾中建立所有建置輸入和輸出。

若要使用自訂 up-to日期檢查:

  1. Toolset.targets 檔案中新增 NoVCDefaultBuildUpToDateCheckProvider 功能,以停用預設 up-to日期檢查:

    <ItemGroup>
      <ProjectCapability Include="NoVCDefaultBuildUpToDateCheckProvider" />
    </ItemGroup>
    
  2. 實作您自己的 IBuildUpToDateCheckProvider

項目升級

預設.vcxproj項目升級程式

默認.vcxproj項目升級程式會變更 PlatformToolsetApplicationTypeRevision、MSBuild 工具組版本和 .NET Framework。 最後兩個一律會變更為 Visual Studio 版本預設值,但 PlatformToolsetApplicationTypeRevision 可由特殊 MSBuild 屬性控制。

升級程式會使用這些準則來決定是否可以升級專案:

  1. 對於定義 ApplicationTypeApplicationTypeRevision的專案,有一個資料夾的修訂編號高於目前的修訂編號。

  2. 屬性 _UpgradePlatformToolsetFor_<safe_toolset_name> 定義給目前的工具組,而且其值不等於目前的工具組。

    在這些屬性名稱中,<safe_toolset_name> 代表工具組名稱,其中包含以底線取代的所有非英數位元(_)。

當專案可以升級作業時,它會進行 方案重新定位。 如需詳細資訊,請參閱 IVsTrackProjectRetargeting2

如果您想要在 方案總管中裝飾專案名稱, 專案使用特定工具組時,請定義 _PlatformToolsetShortNameFor_<safe_toolset_name> 屬性。

如需 _UpgradePlatformToolsetFor_<safe_toolset_name>_PlatformToolsetShortNameFor_<safe_toolset_name> 屬性定義的範例,請參閱 Microsoft.Cpp.Default.props 檔案。 如需使用方式的範例,請參閱 $(VCTargetPath)\Microsoft.Cpp.Platform.targets 檔案。

自定義項目升級程式

若要使用自定義項目升級程序物件,請實作MEF元件,如下所示:

/// </summary>
[Export("MyProjectUpgrader", typeof(IProjectRetargetHandler))]
[Export(typeof(IProjectRetargetHandler))]
[ExportMetadata("Name", "MyProjectUpgrader")]
[OrderPrecedence(20)]
[PartMetadata(ProjectCapabilities.Requires, ProjectCapabilities.VisualC)]

internal class MyProjectUpgrader: IProjectRetargetHandler
{
    // ...
}

您的程式代碼可以匯入並呼叫預設.vcxproj升級程式物件:

// ...
[Import("VCDefaultProjectUpgrader")]
// ...
    IProjectRetargetHandler Lazy<IProjectRetargetHandler>
    VCDefaultProjectUpgrader { get; set; }
// ...

IProjectRetargetHandler 定義於 Microsoft.VisualStudio.ProjectSystem.VS.dll,類似於 IVsRetargetProjectAsync

定義 VCProjectUpgraderObjectName 屬性,告知項目系統使用您的自定義升級程式物件:

<PropertyGroup>
  <VCProjectUpgraderObjectName>MyProjectUpgrader</VCProjectUpgraderObjectName>
</PropertyGroup>

停用專案升級

若要停用專案升級,請使用 NoUpgrade 數值:

<PropertyGroup>
  <VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
</PropertyGroup>

專案的快取與延展性

為了改善在Visual Studio 2017中使用大型C++解決方案時的效能,引進了 專案快取。 它會實作為填入項目數據的 SQLite 資料庫,然後用來載入專案,而不需要將 MSBuild 或 CPS 專案載入記憶體中。

由於從快取載入的 .vcxproj 專案缺乏 CPS 物件,因此無法建立匯入 UnconfiguredProjectConfiguredProject 的擴充功能 MEF 元件。 為了支援擴充性,當 Visual Studio 偵測到專案是否使用 (或可能使用) MEF 延伸模組時,不會使用專案快取。

這些項目類型一律會完整載入,且記憶體中有 CPS 物件,因此會為其建立所有 MEF 延伸模組:

  • 新創專案

  • 具有自定義升級程序的專案,也就是說,這些專案定義了 VCProjectUpgraderObjectName 屬性

  • 不以桌面版 Windows 為目標的專案,也就是定義 ApplicationType 屬性

  • 共用項目專案 (.vcxitems) 和透過匯入 .vcxitems 專案來參考這些專案的任何專案。

如果未偵測到這些條件,則會建立專案快取。 快取包括來自 MSBuild 專案的所有資料,這些資料是回答 get 查詢在 VCProjectEngine 介面上的必要條件。 這表示延伸模組在 MSBuild 屬性和目標檔案層級所進行的所有修改,應該能在從快取載入的項目中順利運行。

發送您的擴充功能

如需如何建立 VSIX 檔案的詳細資訊,請參閱 傳送 Visual Studio 延伸模組。 如需如何將檔案新增至特殊安裝位置的資訊,例如,若要在 $(VCTargetsPath)下新增檔案,請參閱 在延伸模組資料夾外部安裝

其他資源

Microsoft建置系統 (MSBuild) 會提供專案檔的建置引擎和可延伸的 XML 格式。 您應該熟悉 的基本 MSBuild 概念,以及如何 適用於 Visual C++ 的 MSBuild 運作,以擴充 Visual C++ 項目系統。

Managed Extensibility Framework (MEF) 提供 CPS 和 Visual C++ 項目系統所使用的擴充 API。 如需了解 CPS 如何使用 MEF 的概觀,請參閱 MEF 概觀中的VSProjectSystem,以及 CPS 和 MEF

您可以自定義現有的建置系統,以新增建置步驟或新的文件類型。 如需詳細資訊,請參閱 MSBuild (Visual C++) 概觀使用專案屬性