2009-06-02 17 views
28

sự khác biệt giữa việc tạo một mục bên trong một mục tiêu như thế này là gì:CreateItem vs ItemGroup

<Target Name="DoStuff"> 
    <CreateItem Include="@(IntermediateAssembly)" > 
     <Output TaskParameter="Include" ItemName="FileWrites"/> 
    </CreateItem> 
</Target> 

và như thế này:

<Target Name="DoStuff"> 
    <ItemGroup> 
     <FileWrites Include="@(IntermediateAssembly)" /> 
    </ItemGroup> 
</Target> 

Khi bạn sẽ sử dụng một hay khác và tại sao?

Trả lời

27

Trong các phiên bản MSBuild trước 3.5 bạn không thể xác định thuộc tính hoặc mục bên trong mục tiêu (như trong ví dụ thứ hai). Vì vậy, một tác vụ đã được sử dụng thay thế (CreateItem và CreateProperty)

Nếu bạn đang sử dụng ToolsVersion 3.5 thì bạn không cần phải sử dụng CreateItem nữa (mặc dù bạn vẫn có thể nếu bạn thích).

Cuối cùng, cả hai đều tạo mục giống nhau, với cùng phạm vi. Sử dụng cú pháp thứ hai dễ đọc hơn và việc thiết lập dữ liệu meta tùy chỉnh dễ dàng hơn nhiều (theo ý kiến ​​của tôi).

LƯU Ý: Phiên bản 3.5 của MSBuild được cài đặt với .NET 3.5. Mặc dù bạn cần phải xác định ToolsVersion="3.5" trong thẻ Project của tệp MSBuild của bạn để sử dụng 3,5 tính năng.

Trong trường hợp bạn tự hỏi, tôi nhận được hầu hết thông tin này từ sách Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build mà tôi thực sự thích (nhưng không liên kết với bất kỳ cách nào).

+0

Cảm ơn bạn rất nhiều, đây chỉ là những gì tôi muốn biết! Tôi sẽ phải xem cuốn sách đó. – Jake

+2

Đúng là cuốn sách tuyệt vời, tôi thích nó :) :) :) Cảm ơn bạn đã đọc. –

+5

Tôi tìm thấy một sự khác biệt lớn mặc dù: CreateItem sẽ mở rộng các ký tự đại diện cho nó trong Bao gồm thông qua một phép biến đổi như trong khi khai báo ItemGroup sẽ không mở rộng nó . –

7

Tôi không nghĩ câu trả lời được chấp nhận đã xác định sự khác biệt.

Sự khác biệt là:

  • ItemGroup được đánh giá khi kịch bản MSBuild được tải.
  • CreateItem được đánh giá khi mục tiêu được thực hiện

Điều này có thể dẫn đến giá trị khác nhau của Item trong kịch bản.

Lấy ví dụ về Tác vụ thực hiện điều gì đó với tất cả các tệp khớp với "* .txt" trong một thư mục. Nếu kịch bản MSBuild của bạn được tải trong studio trực quan, chỉ có các tệp tồn tại khi VS bắt đầu sẽ ở trong Item nếu bạn sử dụng ItemGroup.

Nếu bạn sử dụng CreateItem - nó sẽ thực hiện tìm kiếm tất cả các tệp * .txt khi đích được thực hiện.

+10

Người hỏi chỉ ra rằng cả hai được gọi từ bên trong một mục tiêu. Từ câu trả lời của bạn, có vẻ như bạn đang suy nghĩ trước các điều khoản MSBuild 3.5. (Khi ItemGroup không thể được đặt bên trong một mục tiêu). Nếu ItemGroup nằm bên trong một target thì nó chỉ là động như thể nó được khai báo thông qua CreateItem. (tức là nó được đánh giá khi mục tiêu được chạy.) (Xem Trang 51 của "Bên trong Công cụ Xây dựng của Microsoft: Sử dụng MSBuild và Team Foundation Build" để tham khảo (hoặc chỉ cần thử nó ra)). – Vaccano

+0

@Vaccano: Một Itemgroup "chỉ là động" bên trong một mục tiêu với ngoại lệ được đề cập bởi Johannes Rudolph trong một bình luận cho câu trả lời đã chọn - "CreateItem sẽ mở rộng các ký tự đại diện cho nó trong Bao gồm thông qua một phép biến đổi" ... trong khi Tuyên bố ItemGroup sẽ không. – CyberMonk

17

CreateItem và CreateProperty đã lỗi thời trong MSBuild 3.5 (mặc dù sẽ luôn tiếp tục hoạt động, tất nhiên). Rõ ràng là chúng ta cần cú pháp quen thuộc cho ItemGroup và PropertyGroup để làm việc bên trong các mục tiêu.

Nhưng ItemGroup bên trong một mục tiêu có một số quyền hạn bổ sung đặc biệt. Nó có thể sửa đổi các mục: ví dụ, điều này sẽ thêm đúng cho tất cả các mục trong danh sách Tài nguyên có siêu dữ liệu có tên là Primary với giá trị true; chỉ khi chưa có Sao chép siêu dữ liệu:

<ItemGroup> 
    <Resources Condition=" '%(Primary)' == 'true' "> 
    <Copy Condition=" '%(Copy)' == '' ">true</Copy> 
    </Resources> 
</ItemGroup> 

Một ma lực khác: bây giờ bạn có thể xóa các mục khỏi danh sách.Ví dụ này sẽ xóa tất cả các mục khỏi danh sách Tài nguyên có loại siêu dữ liệu có giá trị Bitmap:

<ItemGroup> 
    <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/> 
</ItemGroup> 

Những quyền hạn ma thuật này chỉ hoạt động bên trong hiện tại, không phải bên ngoài.

Để biết chi tiết đầy đủ về công cụ này, tôi khuyên bạn nên đánh giá cao cuốn sách của Sayed Hashimi về MSBuild. Nó dễ dàng tìm thấy trên Amazon.

Nhóm Dan - msbuild.

1

Là một thông tin bổ sung cho những người khác đi qua đây: Build-Engine có chứa API để xây dựng các dự án MSBuild không hỗ trợ thêm ItemGroups theo cách mới vào Target. Ở đây bạn S have phải sử dụng cách cũ.

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