控制建置系統放置二進位檔的地方
預設建置流程 (如 DefaultTemplate.xaml 中所定義) 會將它所編譯的二進位檔從所有程式碼專案置放到單一目錄。 不過在某些情況下,您會想要將二進位檔組成更細微、有組織的目錄結構。
您可以使用本主題中的技巧,建立一個自訂建置流程,讓它將二進位檔置放到您所設計的目錄結構。 您也可以使用相同的準則,以不同的方式自訂建置流程。 本主題將說明下列技巧:
自訂建置流程的 Windows 工作流程區段。 您應該變更這個區段以自訂建置流程的大部分層面,但編譯及處理二進位檔除外。 本主題特別說明如何執行下列工作:
修改預設範本 (DefaultTemplate.xaml) 的複本,藉此建立自訂建置流程。
宣告並使用引數,將資料傳入工作流程。
宣告並使用變數,在整個工作流程收集及傳遞資料。
修改工作流程使用 MSBuild 活動呼叫 MSBuild 的方式。
將某個檔案下載至組建伺服器,並使用 ConvertWorkspaceItem 活動讓該檔案供建置流程使用。
自訂建置流程的 MSBuild 區段。 只要變更這個區段,即可更有效率地自訂二進位檔的編譯及處理方式。 本主題特別說明如何執行下列工作:
將引數傳遞至 MSBuild,然後在程式碼專案中使用這些引數變更編譯過的二進位檔的處理方式。
設定自己的 MSBuild 項目的集中式通用程式碼程式庫,例如屬性群組或目標。 透過設定這種類型的程式庫,您讓小組能夠輕鬆地重複使用及修改一些重要的建置流程邏輯。
![]() |
---|
本主題涵蓋三種類型的程式碼專案:C#、C++ 和 Visual Basic。 但是,您可以使用其他類型的程式碼專案的技巧。 |
本主題內容
必要的使用權限
預設組建流程放置編譯過的二進位檔的位置
使用內嵌在每個程式碼專案中的邏輯組織編譯過的二進位檔
流程概觀
遵循步驟概觀
建立組建定義和 CustomOutputDirInline 自訂建置流程範本
將置放資料夾邏輯內嵌在程式碼專案中
使用兩個集中式檔案中維護的邏輯組織編譯過的二進位檔
流程概觀
遵循步驟概觀
建立含有置放資料夾邏輯的 MSBuild 通用程式碼檔
建立組建定義和 CustomOutputDirImport 自訂建置流程範本
更新 OurTeamBuild 組建定義
將置放資料夾邏輯匯入程式碼專案
後續步驟
必要的使用權限
若要執行下列程序,您必須將下列權限設為 [允許]:
編輯組建定義:
[簽出] 和 [簽入] 相關的版本控制目錄。
佇列組建:
如需詳細資訊,請參閱 Team Foundation Server 使用權限。
預設組建流程放置編譯過的二進位檔的位置
不管工作怎樣分成程式碼專案和方案,預設建置流程會將所有編譯過的二進位檔放入置放資料夾中的單一子目錄。 例如,您可能有下列方案和程式碼專案:
SolutionA
CPPWin32ConsoleApp (Visual C++ 主控台應用程式)
CSharpConsoleApp (Visual C# 主控台應用程式)
SolutionB
- VBConsoleApp (Visual Basic 主控台應用程式)
下圖說明二進位檔編譯成為 DefaultTemplate.xaml 中指定之流程的一部分後,MSBuild 置放二進位檔的方式和位置。
使用內嵌在每個程式碼專案中的邏輯組織編譯過的二進位檔
您可以指定編譯過的二進位檔將會放入與方案和程式碼專案結構相符的子目錄結構。
流程概觀
下圖說明如何在高的層級實作這類建置流程:
遵循步驟概觀
簡言之,您可以執行下列步驟來建立這類以 DefaultTemplate.xaml 為基礎的自訂建置流程:
組建定義和建置流程範本
建立組建定義 (命名為例如 OurTeamBuild)。 在 [流程] 索引標籤上,以新的建置流程範本 (命名為例如 CustomOutputDirInline.xaml) 為組建定義的基礎。
於 CustomOutputDirInline.xaml,在編譯程式碼的 Run MSBuild for Project 活動的執行個體中執行下列步驟:
移除 OutDir 屬性的值讓它變成空字串,以便停用 Run MSBuild for Project 活動的這個屬性。
注意事項
如果不進行此變更,OutDir 屬性會覆寫任何您在程式碼專案中實作的自訂目錄結構。
從 BinariesDirectory 變數收集含有組建代理程式之置放資料夾的字串值,然後將該值傳入 MSBuild 引數 (命名為例如 TeamBuildOutDir)。
程式碼專案
- 在 OurTeamBuild 組建編譯的每個程式碼專案中加入適當的項目 (OutputPath 或 OutDir),以定義將在置放資料夾中定義的子目錄結構。
下列小節將詳細說明如何執行這些步驟。
建立組建定義和 CustomOutputDirInline 自訂建置流程範本
只要建立組建定義並以新的建置流程範本為它的基礎,即可奠定建置流程基礎。
若要建立組建定義和建置流程範本
建立組建定義。
在 [一般] 索引標籤上,指定組建定義的名稱 (例如 OurTeamBuild)。
在 [流程] 索引標籤上,加入要建置的方案。
如需詳細資訊,請參閱建立基本組建定義。
在 OurTeamBuild 組建定義的 [流程] 索引標籤上,將 [建置流程範本] 設為名為 CustomOutputDirInline.xaml 且以 [預設範本] (DefaultTemplate.xaml) 為基礎的新建置流程範本。
如需詳細資訊,請參閱建立並使用自訂建置流程範本。
在 [原始檔控制總管] 中,開啟 Team 專案並顯示含有建置流程範本的資料夾。
根據預設,此子目錄名稱為 BuildProcessTemplates。
簽出後再按兩下您之前在這個程序中建立的 CustomOutputDirInline.xaml 檔案。
在工作流程設計工具中,尋找 Run MSBuild for Project 活動的第二個執行個體,這個活動位於下列結構:
順序 (Sequence) >
在代理程式上執行 (AgentScope) >
嘗試編譯、測試及關聯變更集與工作項目 (TryCatch [Try]) >
順序 (Sequence) >
編譯、測試及關聯變更集與工作項目 (Parallel) >
嘗試編譯和測試 TryCatch [Try] >
編譯和測試 Sequence >
針對 BuildSettings.PlatformConfigurations 中的每個組態 ForEach [Body] >
組態的編譯和測試 Sequence >
如果 BuildSettings.HasProjectsToBuild If [Then] >
針對 BuildSettings.ProjectsToBuild 中的每個專案 ForEach [Body] >
嘗試編譯專案 TryCatch [Try] >
編譯專案 Sequence >
對專案執行 MSBuild
如需如何巡覽這個結構的詳細資訊,請參閱在複雜的 Windows 工作流程中巡覽。
以滑鼠右鍵按一下 Run MSBuild for Project 活動,然後按一下 [屬性]。
在 [屬性] 窗格中移除 OutDir 方塊中的資料,以便將這個屬性設為空字串。
在 [屬性] 窗格中將 CommandLineArguments 屬性設為下列值:
String.Format("/p:SkipInvalidConfigurations=true;TeamBuildOutDir=""{0}"" {1}", BinariesDirectory, MSBuildArguments)
儲存 CustomOutputDirInline.xaml。
在 [原始檔控制總管] 中,將所做的變更簽入這個檔案。
將置放資料夾邏輯內嵌在程式碼專案中
您已建立了組建定義和自訂建置流程範本,所以現在必須在這個建置流程編譯的每個程式碼專案中內嵌目錄結構邏輯。
![]() |
---|
您無法在工作流程本身中內嵌這個邏輯,因為 DefaultTemplate.xaml 工作流程不會透過 MSBuild 編譯器反覆及執行每個專案, 而是會呼叫 MSBuild 一次,編譯所有方案和專案。 |
若要內嵌置放資料夾邏輯
在 [原始檔控制總管] 中,開啟 OurTeamBuild 組建定義建置的方案。
將必要的輸出目錄項目加入至方案中的每個程式碼專案。 對 Managed 程式碼專案 (如 Visual C# 或 Visual Basic) 來說,這個屬性為 OutputPath。 對 Visual C++ 專案來說,這個屬性為 OutDir。 針對方案中的每個程式碼專案,遵循下列步驟:
在 [方案總管] 中,以滑鼠右鍵按一下專案。 如果 [卸載專案] 命令可以使用,請按一下這個命令。
以滑鼠右鍵按一下專案,然後按一下 [編輯 ProjectName]。
請執行下列其中一個步驟:
如果專案是 Managed 程式碼專案 (如 Visual C# 或 Visual Basic):加入 OutputPath 項目。 您必須將這個項目放在程式碼專案中的最後一個 OutputPath 項目後面,如下列範例所示:
<Project DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003 ..."> ... <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86'"> ... <OutputPath>bin\Debug\</OutputPath> ... </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> ... <OutputPath>bin\Release\</OutputPath> ... </PropertyGroup> <PropertyGroup Condition="$(TeamBuildOutDir) != '' "> <OutputPath>$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)</OutputPath> </PropertyGroup>
如果專案是 Visual C++ 專案:加入 OutDir 項目。 您必須將這個項目放在匯入 Microsoft.Cpp.targets 的項目前面,如下列範例所示:
<Project DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003 ..."> ... <PropertyGroup Condition="$(TeamBuildOutDir) != '' "> <OutDir>$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)\</OutDir> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project>
儲存程式碼專案。
在 [方案總管] 中,以滑鼠右鍵按一下方案,然後按一下 [簽入]。
針對 OurTeamBuild 建置的每個方案,重複執行這些步驟。
使用兩個集中式檔案中維護的邏輯組織編譯過的二進位檔
如果您有許多程式碼專案需要維護,您可以在兩個共用檔案中保留 OutputPath 和 OutDir 項目的情況下,改進上節所述的流程。 如果採用這種方法,只要修改兩個集中式檔案而不是每個程式碼專案,即可更輕鬆地變更置放資料夾的目錄結構。
流程概觀
下圖說明如何在高的層級實作這類建置流程:
遵循步驟概觀
簡言之,您必須執行下列步驟來建立這類以 DefaultTemplate.xaml 為基礎的自訂建置流程:
在 [原始檔控制總管] 中,建立要包含 MSBuild 通用程式的目錄 (命名為例如 $/OurTeam/BuildProcessMSBuild) 來。 在這個目錄中,建立並儲存 MSBuild 檔案,這些檔案會定義將在置放資料夾中定義的子目錄結構。
組建定義和建置流程範本
依照下列步驟來更新組建定義 (命名為例如 OurTeamBuild):
在 [工作區] 索引標籤上,對應 $/OurTeam/BuildProcessMSBuild 目錄。
在 [流程] 索引標籤上,以新的建置流程範本 (命名為例如 CustomOutputDirImport.xaml) 為組建定義的基礎。
在 CustomOutputDirImport.xaml 中,依照下列步驟進行:
將 LocalPathToMSBuildCode 宣告為 String 變數,它的作用範圍只在 Run On Agent 活動內。
將 ServerPathToMSBuildCode 宣告為引數。
加入這個引數後,必須修改 OurTeamBuild 定義。 在 [流程] 索引標籤上,輸入 $/OurTeam/BuildProcessMSBuild 做為此建置流程參數的值。
於 Run on Agent > 活動,在 Try Compile, Test, and Associate Changesets and Work Items [Try] 活動前面加上 ConvertWorkspaceItem 活動,將 ServerPathToMSBuildCode 引數轉換成 MSBuild 可以處理的組建代理程式上的本機路徑。 然後將這個值放入 LocalPathToMSBuildCode 變數。
在編譯程式碼的 Run MSBuild for Project 活動的執行個體中,遵循下列步驟:
移除 OutDir 屬性的值讓它變成空字串,以便停用 Run MSBuild for Project 活動的這個屬性。
注意事項
如果不進行此變更,OutDir 屬性會覆寫任何您在程式碼專案中實作的自訂目錄結構。
從 BinariesDirectory 變數收集含有組建代理程式之置放資料夾的字串值,然後該值傳入 MSBuild 做為引數 (命名為例如 TeamBuildOutDir)。
將 LocalPathToMSBuildCode 的值傳入 MSBuild 做為引數 (命名為例如 CommonMSBuildCode)。
程式碼專案
- 在 OurTeamBuild 編譯的每個程式碼專案中,於適當位置加入 <Import /> 項目。
下列小節將詳細說明如何遵循這些步驟。
建立含有置放資料夾邏輯的 MSBuild 通用程式碼檔
對於這種方法,您可以從建立目錄和兩個 MSBuild 專案檔開始。 這些檔案的邏輯會定義將在置放資料夾中定義的子目錄結構。
若要建立檔案
在 [原始檔控制總管] 中,執行下列其中一個步驟:
尋找儲存 MSBuild 通用程式碼的目錄。
建立儲存 MSBuild 通用程式碼的目錄,並命名為例如 $/OurTeam/BuildProcessMSBuild。
如果 [未對應] 連結出現在 [原始檔控制總管] 頂端的 [本機路徑] 標籤旁邊,請按一下該連結將伺服器目錄對應至本機工作區中的適當目錄。
建立並儲存下列檔案,然後加以簽入至 $/OurTeam/BuildProcessMSBuild:
含有 Managed 程式碼專案 (如 Visual C# 或 Visual Basic) 之置放資料夾邏輯的檔案 (命名為例如 ManagedCodeProjectOutDir.targets)。
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Condition="$(TeamBuildOutDir) != '' "> <OutputPath>$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)</OutputPath> </PropertyGroup> </Project>
含有 Visual C++ 程式碼專案之置放資料夾邏輯的檔案 (命名為例如 CPPCodeProjectOutDir.targets)。
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Condition="$(TeamBuildOutDir) != '' "> <OutDir>$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)\</OutDir> </PropertyGroup> </Project>
建立組建定義和 CustomOutputDirImport 自訂建置流程範本
您可以重複使用您之前在本主題中建立並命名為 OurTeamBuild 的組建定義。 您將會以新的建置流程範本為它的基礎,並進行一些額外的調整。
若要建立組建定義和建置流程範本
在 [Team 總管] 中,以滑鼠右鍵按一下 OurTeamBuild,然後按一下 [編輯]。
按一下 [流程] 索引標籤,然後將 [建置流程範本] 設為名為 CustomOutputDirImport.xaml 且以 [預設範本] (DefaultTemplate.xaml) 為基礎的新建置流程範本。
如需詳細資訊,請參閱建立並使用自訂建置流程範本。
在 [原始檔控制總管] 中,開啟 Team 專案並顯示含有建置流程範本的資料夾。 根據預設,此子目錄名稱為 BuildProcessTemplates。
簽出後再按兩下您之前在這個程序中建立的 CustomOutputDirImport.xaml 檔案。
在工作流程設計工具中,尋找 Run on Agent 活動,這個活動位於下列結構:
順序 (Sequence) >
在代理程式上執行 (AgentScope) >
如需如何巡覽這個結構的詳細資訊,請參閱在複雜的 Windows 工作流程中巡覽。
在視窗底部,按一下 [引數]。
在 [引數] 窗格中,建立一個引數並命名為 ServerPathToMSBuildCode。
在 [屬性] 窗格中,選取 [IsRequired] 核取方塊。
在視窗底部,按一下 [變數]。
在 [變數] 窗格中,宣告名為 LocalPathToMSBuildCode 的變數具有 String 型別而且範圍為 Run On Agent。
將 ConvertWorkspaceItem 活動從 [工具箱] 的 [Team Foundation Build 活動] 區段拖曳至 Initialize Workspace 與 If CreateLabel 活動之間的位置。
注意事項
如果 [Team Foundation Build 活動] 區段沒有出現在 [工具箱] 中,您可以從 Microsoft.TeamFoundation.Build.Workflow.dll 組件手動加入這個區段。 如需詳細資訊,請參閱 How to: Add Activities to the Toolbox。
以滑鼠右鍵按一下 ConvertWorkspaceItem 活動,然後按一下 [屬性]。
在 [屬性] 窗格中設定下列屬性值:
顯示名稱:Get Local Path to MSBuild Code
輸入:ServerPathToMSBuildCode
結果:LocalPathToMSBuildCode
工作區:Workspace
尋找 Run MSBuild for Project 活動的第二個執行個體,這個活動位於下列結構:
順序 (Sequence) >
在代理程式上執行 (AgentScope) >
嘗試編譯、測試及關聯變更集與工作項目 (TryCatch [Try]) >
順序 (Sequence) >
編譯、測試及關聯變更集與工作項目 (Parallel) >
嘗試編譯和測試 TryCatch [Try] >
編譯和測試 Sequence >
針對 BuildSettings.PlatformConfigurations 中的每個組態 ForEach [Body] >
組態的編譯和測試 Sequence >
如果 BuildSettings.HasProjectsToBuild If [Then] >
針對 BuildSettings.ProjectsToBuild 中的每個專案 ForEach [Body] >
嘗試編譯專案 TryCatch [Try] >
編譯專案 Sequence >
對專案執行 MSBuild
如需如何巡覽這個結構的詳細資訊,請參閱在複雜的 Windows 工作流程中巡覽。
以滑鼠右鍵按一下 Run MSBuild for Project 活動,然後按一下 [屬性]。
在 [屬性] 窗格中移除 OutDir 方塊中的資料,以便將這個屬性設為空字串。
在 [屬性] 窗格中將 CommandLineArguments 屬性設為下列值:
String.Format("/p:SkipInvalidConfigurations=true;CommonMSBuildCode=""{0}"";TeamBuildOutDir=""{1}"" {2}", LocalPathToMSBuildCode, BinariesDirectory, MSBuildArguments)
儲存 CustomOutputDirImport.xaml。
在 [原始檔控制總管] 中,將所做的變更簽入這個檔案。
更新 OurTeamBuild 組建定義
接下來,您必須變更 OurTeamBuild 組建定義。
若要更新組建定義
在 [Team 總管] 中,依序展開您正在處理的 Team 專案和 [組建] 資料夾,然後以滑鼠右鍵按一下 OurTeamBuild 組建定義,再按一下 [編輯組建定義]。
按一下 [工作區] 索引標籤,然後加入有下列值的項目:
狀態:作用中
原始檔控制資料夾:$/OurTeam/BuildProcessMSBuild
組建代理程式資料夾:$(SourceDir)\BuildProcessMSBuild
按一下 [流程] 索引標籤,然後在 [ServerPathToMSBuildCode] 方塊中輸入 $/OurTeam/BuildProcessMSBuild。
儲存組建定義。
將置放資料夾邏輯匯入程式碼專案
在建立組建定義和自訂建置流程範本之後,您必須更新程式碼專案來匯入目錄結構邏輯。
若要匯入置放資料夾邏輯
在 [原始檔控制總管] 中,按兩下 OurTeamBuild 建置的方案。
針對方案中的每個程式碼專案,遵循下列步驟:
在 [方案總管] 中,以滑鼠右鍵按一下專案。 如果 [卸載專案] 命令可以使用,請按一下這個命令。
以滑鼠右鍵按一下專案,然後按一下 [編輯 ProjectName]。
請執行下列其中一個步驟:
如果專案是 Managed 程式碼專案 (如 Visual C# 或 Visual Basic):將 Import 項目加在程式碼專案中的最後一個 OutputPath 項目後面,如下列範例所示:
<Project DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003 ..."> ... <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86'"> ... <OutputPath>bin\Debug\</OutputPath> ... </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> ... <OutputPath>bin\Release\</OutputPath> ... </PropertyGroup> <Import Condition=" $(CommonMSBuildCode) != ''" Project="$(CommonMSBuildCode)\ManagedCodeProjectOutDir.targets"/>
如果專案是 Visual C++ 專案:將 Import 項目加在匯入 Microsoft.Cpp.targets 的項目前面,如下列範例所示:
<Project DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003 ..."> ... <Import Condition=" $(CommonMSBuildCode) != ''" Project="$(CommonMSBuildCode)\CPPCodeProjectOutDir.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project>
儲存程式碼專案。
在 [方案總管] 中,以滑鼠右鍵按一下方案,然後按一下 [簽入]。
針對 OurTeamBuild 建置的每個方案,重複上述步驟。
後續步驟
若要採取進一步行動,您可以執行下列工作:
修改置放資料夾邏輯。為了符合小組的需求,您可以修改前面小節所提供的 OutputPath 和 OutDir 項目的內容。
將自訂程式碼專案另存為範本。如果小組將建立許多程式碼專案,您可以在新的程式碼專案中自動包含自訂 MSBuild 邏輯。 在 [方案總管] 中按一下程式碼專案,開啟 [專案] 功能表,然後按一下 [匯出範本]。
其他資源
您可以從 Microsoft 網站上的下列主題中找到其他資訊: