2009-01-23 24 views
10

Tôi đang xem xét chạy MSBuild từ một kịch bản Powershell bằng cách khai thác trực tiếp vào các hội đồng MSBuild (như trái ngược với tìm kiếm đường dẫn cài đặt MSBuild và bắt đầu msbuild.exe như là một tiến trình con).Làm thế nào để chạy MSBuild từ Powershell mà không cần quá trình msbuild.exe sinh sản?

Có ai đã làm điều này không? Điều gì sẽ là cách đơn giản nhất, đơn giản nhất để chạy bản dựng? Có bất kỳ ưu điểm/khuyết điểm nào đối với một trong hai kỹ thuật mà bạn muốn chỉ ra không? (Tôi đặc biệt quan tâm đến bất kỳ vấn đề có thể phát sinh từ chạy msbuild trong cùng một process/appdomain như phần còn lại của kịch bản).

Hiện nay suy nghĩ của tôi là một cái gì đó dọc theo những dòng:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') 
[void][Microsoft.Build.BuildEngine.Engine]::GlobalEngine.BuildProjectFile("path/main.proj") 

Trả lời

14

Lời gọi xây dựng nhúng đơn giản nhất đã hoạt động và sản xuất là:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') 
$engine = New-Object Microsoft.Build.BuildEngine.Engine 
$engine.RegisterLogger((New-Object Microsoft.Build.BuildEngine.ConsoleLogger)) 
$engine.BuildProjectFile('fullPath\some.proj') 

Tuy nhiên, nó quay ra nhúng MSBuild trực tiếp trong Powershell (V1) là có vấn đề:

'MSBUILD : warning MSB4056: The MSBuild engine must be called on 
a single-threaded-apartment. Current threading model is "MTA". 
Proceeding, but some tasks may not function correctly.' 

Tại sao oh tại sao chúng ta vẫn phải trả thuế COM trong năm 2009 trong khi làm việc trong một môi trường được quản lý?

Kết luận của tôi là nhúng MSBuild vào Powershell (V1) không phải là một ý tưởng hay.Để tham khảo, tôi cũng bao gồm các phương pháp tiếp cận dựa trên quá trình tôi đã kết thúc bằng:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') 
$msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile("msbuild.exe", "VersionLatest") 
&$msbuild fullPath\some.proj 
3

Một cách tiếp cận khác nhau và có khả năng sử dụng được nhiều hơn sẽ được thực hiện một lệnh msbuild. MsBuild có một API tốt và có rất nhiều ví dụ về cách sử dụng nó từ một ngôn ngữ được biên dịch như C#/VB. Nó sẽ rất dễ dàng để xây dựng một cmdlet mà sẽ cung cấp một cú pháp đẹp hơn cho kịch bản PowerShell của bạn.

+3

Vâng đó là câu hỏi của tôi - bạn có bất kỳ liên kết nào đến "nhiều mẫu về cách sử dụng nó" hay cung cấp cho riêng bạn? –

5

Tôi rất muốn đề xuất xem PSake.

Hãy để tôi trích dẫn một phần của trang đó:

Ghi psake đó là cú pháp đường xung quanh PowerShell. Vì vậy, bất cứ điều gì bạn có thể làm trong PowerShell, bạn có thể làm trong psake. Điều đó có nghĩa là bạn có thể chạy MSBuild, NAnt hoặc các tập lệnh khác. Không cần phải thay thế hoàn toàn hệ thống xây dựng hiện tại của bạn. Bạn có thể sử dụng psake để tự động hóa và mở rộng nó!

psake tự động thêm phiên bản .NET Framework phù hợp vào đường dẫn của nó. Vì vậy, bạn có thể truy cập MSBuild, csc.exe, vbc.exe hoặc bất kỳ công cụ nào khác được cài đặt trong $ env: windir \ Microsoft.NET \ Framework \ $ version \ mà không có đường dẫn đầy đủ.

+2

Xin vui lòng, chúng ta hãy không đi vào cuộc tranh luận triết học về 'msbuild sucks, sử dụng xây dựng PowerShell dựa trên thay vì' vì đó không phải là câu hỏi của tôi, thực sự. –

+0

Bạn đang nói về cuộc tranh luận triết học nào? Bạn đã đọc trang chưa? Nó cung cấp một cách đơn giản để bọc MSBuild. – EBGreen

+0

Có, tôi đã đọc trang. Và nó mô tả công cụ xây dựng "không có dấu ngoặc kép thuế" giống như cào này. Tôi đã sử dụng cào trước khi tôi chuyển sang msbuild và tôi sẽ không trở lại :-). Cơ chế psake sử dụng để gọi msbuild là nó thêm nó vào 'đường dẫn' - tức là quá trình bên ngoài. Đó chính là điều tôi không muốn. –

3

Tôi đang tìm kiếm điều tương tự này. Theo chỉ dẫn của JaredPar, tôi đã tìm thấy những điều sau đây:

Đây là cách thực hiện lệnh ghép ngắn.

http://bartdesmet.net/blogs/bart/archive/2008/02/03/easy-windows-powershell-cmdlet-development-and-debugging.aspx

Các MSBuild API là một phần của những không gian tên:

Microsoft.Build.Framework 

Microsoft.Build.BuildEngine 

Và các tài liệu MSBuild có thể được tìm thấy ở đây (đây là chi tiết cho đầy đủ hơn để đáp lại câu hỏi của bạn):

http://msdn.microsoft.com/en-us/library/wea2sca5.aspx

+0

Cảm ơn bạn Anthony, nhưng việc chuyển mã từ PowerShell thuần túy thành cmdlet thực sự chỉ là tối ưu hóa hiệu suất/tiện lợi. Tôi quan tâm đến các bước/mã cũng như gotchas để sử dụng trực tiếp Microsoft.Build.BuildEngine. Tôi có thể di chuyển impl thực tế giữa ps1 và cmdlet khá dễ dàng. –

+0

Tôi có tập lệnh msbuild ở nhiều nơi khác nhau và tôi muốn có thể chạy một thứ từ một vị trí trung tâm. Nếu bạn kết thúc với một câu trả lời làm việc, tôi rất muốn nhìn thấy một bài đăng blog hoặc một cái gì đó. –

+0

Xem thêm http://stackoverflow.com/questions/78069/any-good-powershell-msbuild-tasks –

0

Ngày xửa ngày xưa tôi đã chơi với chạy tăng cường MSBuild xây dựng các quy trình (như, bỏ qua một số bộ phận của xây dựng hơn tích cực).

Có hai lựa chọn:

  1. chủ MSBuild trong tiến trình riêng của bạn bằng cách tải DLL của nó.
  2. Spawn MSBuild.exe cách thông thường và sau đó tiêm vào nó (ví dụ: logger cung cấp một cách phong nha).

Tôi đã triển khai cả hai và phải từ bỏ # 1 vì nó không đủ linh hoạt.

Ví dụ, MSBuild có tải trọng chuyển hướng ràng buộc lắp ráp trong tệp .config của nó.

Quá trình Visual Studio (devenv.exe) cũng lưu trữ MSBuild với API của nó kết thúc sao chép chúng vào devenv.exe.config của nó. Mine .exe.config cũng phải có những cái này, nhưng nó tuân thủ bạn với một phiên bản MSBuild cụ thể. Và, tất nhiên, bạn phải sửa đổi cấu hình. Mà không phải là một lựa chọn với PS thực sự, vì vậy tôi nghi ngờ nếu bạn có thể nhận được một giải pháp thực sự ổn định.

Các vấn đề liên quan