我想我會更新我以前的答案,因爲我已經花了很多時間和精力創造我自己的解決此問題的。解決問題的方法比簡單地解決問題要全面一些,但我試圖消除這個問題,並且避免像這樣的未來衝擊。
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 - 由於微軟的這一改變幾乎使這項工作脫軌!
乾杯。
+1。 –
當你說MSBuild有確認的錯誤時,你是什麼意思?有沒有在MSDN中的這個問題的鏈接,所以我可以跟蹤它,看看微軟是否有任何指導? –
正是在這裏 http://connect.microsoft.com/VisualStudio/feedback/details/586875/msbuild-4-0-incorrectly-processes-project-dependencies-specified-in-solution-file 固定爲4.5 –