tôi nghĩ rằng tôi muốn cập nhật câu trả lời trước đây của tôi, như tôi đã dành rất nhiều thời gian và công sức tạo ra cách giải quyết của riêng tôi cho vấn đề này. Các công việc xung quanh là một chút toàn diện hơn chỉ đơn giản là sống với vấn đề, nhưng tôi đã cố gắng để loại bỏ cả hai vấn đề và cách nhiệt chính mình chống lại những cú sốc trong tương lai như thế này.
MSBuild đã bị giảm hạng khi làm việc với các giải pháp, cấu hình hoặc cách khác. MSBuild chỉ được yêu cầu biên dịch các dự án một cách riêng biệt. Thứ tự này xảy ra được tính toán bởi một kịch bản Powershell phân tích các giải pháp và dự án của chúng tôi để xây dựng kế hoạch thực hiện xây dựng Just-In-Time tốt nhất.
chính này (và tôi nghĩ rằng bạn có thể tìm thấy hữu ích) đều được các đoạn sau:
Xác định các giải pháp của tôi
tôi có một danh sách của tất cả các giải pháp trong nền tảng của tôi, và tôi về cơ bản lặp trên mỗi cái này.
$buildPlan = (
@{
solutions = (
@{
name = "DataStorage"
namespace = "Platform.Databases"
},
@{
name = "CoreFramework"
},
@{
namespace = "Platform.Server"
name = "Application1"
},
@{
namespace = "Platform.Server"
name = "Application2"
},
@{
namespace = "Platform.Client"
name = "Application1"
}
)
})
Tôi có một số logic giúp dịch thành con đường vật lý thực tế, nhưng nó rất riêng biệt với nhu cầu của chúng tôi, vì vậy tôi sẽ không liệt kê ở đây. Có thể nói, từ danh sách này, tôi có thể tìm thấy tệp .sln mà tôi cần phân tích cú pháp.
Phân tích các tập tin giải pháp cho các dự án
Với mỗi giải pháp, tôi đọc file sln và cố gắng trích xuất tất cả các dự án chứa bên trong mà tôi sẽ cần phải xây dựng sau này.
Vì vậy, trước hết, xác định tất cả các dự án trong tôi
$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
Và sau đó dịch này vào một danh sách tốt đẹp của dự án mà tôi có thể lặp qua sau đó.
$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
}
}
}
}
tải Visual Studio dự án
Từ phân tích của tôi về tập tin giải pháp, bây giờ tôi có một danh sách các dự án mỗi giải pháp, trong đó điều quan trọng chứa các File Path tương đối từ gốc giải pháp để tìm ra dự án.
$projectDefinition = [xml](Get-Content $csProjectFileName)
$ns = @{ e = "http://schemas.microsoft.com/developer/msbuild/2003" }
$references = @();
1) Xác định các dự án bên ngoài tham chiếu
$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) Xác định các dự án nội bộ tham chiếu
$references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:ItemGroup/e:ProjectReference" -Namespace $ns | % { $_.Node.Name }
3) Sau "Post-xây dựng" các sự kiện như tài liệu tham khảo bên ngoài
$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 }
}
}
Và, vì chúng ta đang ở đó, nhận được một số thông tin cơ bản đầu ra quá
Đây là tiện dụng khi nói đến lặp lại danh sách các dự án xây dựng, như bí quyết nơi để đẩy sản lượng hoặc nơi để tìm đầu ra của người phụ thuộc.
$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
Và ở phần cuối của nó tất cả
Chúng ta chỉ cần chắc chắn rằng chúng tôi không có bất kỳ bản sao, vì vậy tôi ghi lại chỉ là phụ thuộc khác biệt của dự án mã đặc biệt này:
$dependendents = @();
if ($references -ne $null)
{
$buildAction.project.dependencies += $references | where {(!([string]::IsNullOrEmpty($_))) -and ($_ -match "OurCompanyPrefix\.(.*)")} | % { $_.ToLower()} | Select -unique
}
Tôi hy vọng điều này sẽ cung cấp cho bạn đủ thông tin để phân tích cú pháp tệp SLN và PROJ của bạn. Làm thế nào bạn sẽ chọn để nắm bắt và lưu trữ thông tin này tôi nghĩ rằng sẽ phụ thuộc hoàn toàn vào bạn.
Tôi đang ở giữa viết một bài đăng blog chuyên sâu về điều này, trong đó sẽ chứa tất cả các trang trí và khung mà tôi đã bỏ qua ở trên.Bài đăng chưa sẵn sàng, nhưng tôi sẽ liên kết đến bài đăng đó từ bài đăng trước đó: http://automagik.piximo.me/2013/02/just-in-time-compilation.html - Vì sự thay đổi này của Microsoft gần như làm trật bánh công việc này!
Chúc mừng.
+1 vì lý do thứ hai. –
Bạn có ý gì khi nói MSBuild có lỗi xác nhận? Có một liên kết đến vấn đề này trong MSDN vì vậy tôi có thể theo dõi nó và xem nếu Microsoft có bất kỳ hướng dẫn? –
Nó đã ở đây http://connect.microsoft.com/VisualStudio/feedback/details/586875/msbuild-4-0-incorrectly-processes-project-dependencies-specified-in-solution-file cố định trong 4.5 –