この問題に対する独自の回避策を作成するために多くの時間と労力を費やしたので、以前の回答を更新すると思いました。回避策は、単に問題に対処するよりももう少し包括的ですが、問題を排除し、このような将来のショックから身を守ることの両方を試みました.
MSBuild は、ソリューション、構成などの操作から降格されました。MSBuild は、プロジェクトを分離してコンパイルするよう求められるだけです。これが発生する順序は、ソリューションとプロジェクトを解析して最適なジャスト イン タイム ビルド実行計画を作成する Powershell スクリプトによって計算されます。
これの鍵となる (役立つと思うかもしれない) のは、次のスニペットです。
ソリューションの特定
私は自分のプラットフォームのすべてのソリューションのリストを持っており、基本的にこれらのそれぞれについて繰り返します。
$buildPlan = (
@{
solutions = (
@{
name = "DataStorage"
namespace = "Platform.Databases"
},
@{
name = "CoreFramework"
},
@{
namespace = "Platform.Server"
name = "Application1"
},
@{
namespace = "Platform.Server"
name = "Application2"
},
@{
namespace = "Platform.Client"
name = "Application1"
}
)
})
これを実際の物理パスに変換するのに役立ついくつかのロジックがありますが、これは私たちのニーズに合わせてカスタマイズされているため、ここには記載しません。このリストから、解析する必要がある .sln ファイルを見つけることができます。
プロジェクトのソリューション ファイルの解析
ソリューションごとに .sln ファイルを読み取り、後でビルドする必要があるすべてのプロジェクトを抽出しようとしました。
まず、私のすべてのプロジェクトを特定します
$solutionContent = Get-Content $solutionFile
$buildConfigurations += Get-Content $solutionFile | Select-String "{([a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})}\.(Release.*)\|Any CPU\.Build" | % {
New-Object PSObject -Property @{
Name = $_.matches[0].groups[3].value.replace("Release ","");
Guid = $_.matches[0].groups[1].value
}
} | Sort-Object Name,Guid -unique
そして、これをプロジェクトの素敵なリストに変換して、後で反復できるようにします。
$projectDefinitions = $solutionContent |
Select-String 'Project\(' |
ForEach-Object {
$projectParts = $_ -Split '[,=]' | ForEach-Object { $_.Trim('[ "{}]') };
$configs = ($buildConfigurations | where {$_.Guid -eq $projectParts[3]} | Select-Object Name)
foreach ($config in $configs)
{
$santisiedConfig = if ([string]::IsNullOrEmpty($config.Name)){"Release"}else{$config.Name}
if ($projectParts[1] -match "OurCompanyPrefix.")
{
New-Object PSObject -Property @{
Name = $projectParts[1];
File = $projectParts[2];
Guid = $projectParts[3];
Config = $santisiedConfig
}
}
}
}
Visual Studio プロジェクトを読み込む
ソリューション ファイルの解析から、ソリューションごとのプロジェクトのリストが得られました。これには、プロジェクトを見つけるためのソリューション ルートからの相対ファイル パスが含まれています。
$projectDefinition = [xml](Get-Content $csProjectFileName)
$ns = @{ e = "http://schemas.microsoft.com/developer/msbuild/2003" }
$references = @();
1) 外部プロジェクト参照の特定
$references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:ItemGroup/e:Reference" -Namespace $ns | % {$_.Node} | where {$_.Include -match "OurCompanyPrefix" -and $_.HintPath -notmatch "packages"} | % {$_.Include}
2) 内部プロジェクト参照の特定
$references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:ItemGroup/e:ProjectReference" -Namespace $ns | % { $_.Node.Name }
3) 外部参照としての「ビルド後」イベントの追跡
$references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:PropertyGroup/e:PostBuildEvent" -Namespace $ns | where {(!([String]::IsNullOrEmpty($_.Node.InnerText)))} | % {
$postBuildEvents = $_.Node.InnerText.Split("`n")
$projectsReferencedInPostBuildEvents = $postBuildEvents | Select-String "\(SolutionDir\)((\w|\.)*)" | % {$_.Matches[0].Groups[1].Value}
if ($projectsReferencedInPostBuildEvents -ne $null)
{
Write-Output $projectsReferencedInPostBuildEvents | % { $matchedProject = $_; ($releaseConfiguation | ? {$_.File -match $matchedProject}).Name }
}
}
そして、ここまで来たら、基本的な出力情報も取得します。
これは、出力をプッシュする場所や依存関係の出力を見つける場所を知っているので、ビルドするプロジェクトのリストを反復する場合に便利です。
$assemblyName = (Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:PropertyGroup/e:AssemblyName" -Namespace $ns).Node.InnerText
$outputPath = (Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:PropertyGroup[contains(@Condition,'Release|')]/e:OutputPath" -Namespace $ns).Node.InnerText
そして、すべての終わりに
重複がないことを確認する必要があるだけなので、この特定のコード プロジェクトの個別の依存関係だけを記録します。
$dependendents = @();
if ($references -ne $null)
{
$buildAction.project.dependencies += $references | where {(!([string]::IsNullOrEmpty($_))) -and ($_ -match "OurCompanyPrefix\.(.*)")} | % { $_.ToLower()} | Select -unique
}
これにより、SLN ファイルと PROJ ファイルを解析するための十分な情報が得られることを願っています。この情報をどのように取得して保存するかは、完全にあなた次第だと思います。
私はこれについて非常に詳細なブログ投稿を書いている最中です。これには、上記で回避したすべてのトリミングとフレームワークが含まれます。投稿はまだ準備ができていませんが、以前の投稿からリンクします: http://automagik.piximo.me/2013/02/just-in-time-compilation.html - Microsoft によるこの変更以来、この作品を狂わせた!
乾杯。