我很難理解 MSBuild 如何在 Windows 11 上與 NET Core 專案檔案 (csproj) 一起作業。我有 71 個 NET Core C# 專案檔案(可執行檔案、庫、測驗專案)。它們都在 Visual Studio 下或使用 msbuild 批處理作業編譯和運行,這些作業在命令列上構建和發布到發布檔案夾。
本地生成不同的 BIN/* 檔案夾
但是當我在 71 個專案上運行 MSBuild(使用相同的命令列引數)以在本地構建(而不是在本地發布)時,一些專案會產生不同的輸出檔案夾。
其中一些創建 bin/Debug/* 檔案夾,一些創建 bin/x64/Debug/ 檔案夾,一些專案生成這兩種型別的檔案夾。“*”部分是框架/運行時,在我的系統上是 net5.0-windows/win-x64。
這是我典型的 NET 5.0 專案檔案的樣子:
<PropertyGroup>
<Platforms>AnyCPU</Platforms>
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net5.0-windows7.0</TargetFramework>
<SelfContained>false</SelfContained>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
// The IsPublishable setting makes no difference.
// The build operation is not a publishable operation.
</PropertyGroup>
這是我的 MSBuild 命令對所有 71 個專案的樣子
MSBuild /t:Restore;Build /p:Configuration=Debug /p:Platform=x64 /p:RuntimeIdentifier=win-x64 csproj-file-pathname
我做了很多實驗,包括在運行 MSBuild 命令列之前完全洗掉 obj 和 bin 樹,但沒有任何效果。我看不到專案檔案、專案型別(lib 或 exe 或應用程式)和 MSBuild 命令列引數之間有任何可辨別的關系,這些引數可以解釋不同的本地構建輸出檔案夾。
如果專案檔案相同且 MSBuild 引數相同,有誰知道什么會使某些專案創建不同的輸出檔案夾結構(和內容)?
有誰確切知道上面顯示的 msbuild 引數應該生成哪些 bin/* 輸出檔案夾?我花了幾個小時來解決這個問題,但沒有成功。謝謝你。
uj5u.com熱心網友回復:

這是x64的解決方案配置

我使用您正在使用的相同屬性構建解決方案。

我對 MSBuild 非常熟悉,并且知道最終副本要尋找什么屬性。所以我搜索$property OutDir. 這意味著我正在尋找名稱包含 OutDir 的 MSBuild 屬性。

如您所見,我們遇到的情況幾乎與您描述的相同。有些有 bin\x64\Debug,而有些只是 bin\Debug。它們都附加了目標框架,但也附加了運行時識別符號。
如果我們想完全按照 MSBuild 的方式查看專案。我們可以展開評估檔案夾并從背景關系選單中單擊“預處理”。這將是一個怪物 xml。在從 .NET SDK 和您的 repo 匯入所有 .props 和 .targets 之后,這實際上是您的 csproj 完全擴展的榮耀。
您也可以使用選項從 cli 獲取此檔案MSBuild -preprocess[:file]。

發生了很多事情,但實際上我們只是在尋找指導輸出的東西。我知道OutDir 中使用了OutputPath,所以我搜索OutputPath 并跳來跳去。我發現控制默認輸出的特殊 .targets 檔案稱為Microsoft.NET.DefaultOutputPaths.targets. 這是相關部分:
<Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
<Platform Condition="'$(Platform)'==''">AnyCPU</Platform>
<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
<BaseOutputPath Condition="'$(BaseOutputPath)' == ''">bin\</BaseOutputPath>
<BaseOutputPath Condition="!HasTrailingSlash('$(BaseOutputPath)')">$(BaseOutputPath)\</BaseOutputPath>
<OutputPath Condition="'$(OutputPath)' == '' and '$(PlatformName)' == 'AnyCPU'">$(BaseOutputPath)$(Configuration)\</OutputPath>
<OutputPath Condition="'$(OutputPath)' == '' and '$(PlatformName)' != 'AnyCPU'">$(BaseOutputPath)$(PlatformName)\$(Configuration)\</OutputPath>
<OutputPath Condition="!HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
你問題的第一部分終于可以回答了。對于在 AnyCPU 解決方案下構建的專案(即使您指定 x64),您不會$(Platform)在輸出中獲得 。你可以在我的例子中看到:net6lib只有x64在OutDir.
那么運行時識別符號呢,我在這個 .targets 檔案中看不到它。它實際上是稍后在另一個檔案中擴展的:Microsoft.NET.RuntimeIdentifierInference.targets.
帶評論的相關部分
<!--
Append $(RuntimeIdentifier) directory to output and intermediate paths to prevent bin clashes between
targets.
But do not append the implicit default runtime identifier for .NET Framework apps as that would
append a RID the user never mentioned in the path and do so even in the AnyCPU case.
-->
<PropertyGroup Condition="'$(AppendRuntimeIdentifierToOutputPath)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(_UsingDefaultRuntimeIdentifier)' != 'true'">
<IntermediateOutputPath>$(IntermediateOutputPath)$(RuntimeIdentifier)\</IntermediateOutputPath>
<OutputPath>$(OutputPath)$(RuntimeIdentifier)\</OutputPath>
</PropertyGroup>
還有你的輸出部分的最后一部分。$(TargetFramework)在我提到的上一個目標和這個目標之間也插入了那里,但你已經知道了。
這里根本沒有瘋狂。MSBuild 完全按照它被告知要做的事情。
希望這會有所幫助!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475877.html
上一篇:在blazor中添加全域使用指令
下一篇:c#在設計時檢查值
