2008-11-12 22 views
20

Tôi mới làm quen với MSBuild và muốn chơi với nó một chút, nhưng tôi không thể hiểu tại sao điều này không hiệu quả.Sử dụng các tác vụ MSBuild tùy chỉnh từ cùng một giải pháp?

Vì vậy, giải pháp của tôi có hai dự án: "Model" và "BuildTasks". BuildTasks chỉ có một lớp duy nhất:

using Microsoft.Build.Utilities; 

namespace BuildTasks 
{ 
    public class Test : Task 
    { 
     public override bool Execute() 
     { 
      Log.LogMessage("FASDfasdf"); 
      return true; 
     } 
    } 
} 

Và sau đó trong Model.csproj Tôi đã thêm này:

<UsingTask TaskName="BuildTasks.Test" AssemblyFile="$(SolutionDir)src\BuildTasks\bin\BuildTasks.dll" /> 
    <Target Name="AfterBuild"> 
    <Test /> 
    </Target> 

tôi đã thiết lập trật tự xây dựng như vậy "BuildTasks" được xây dựng trước khi " Mô hình". Nhưng khi tôi cố gắng xây dựng Mô hình, tôi nhận được lỗi này:

The "BuildTasks.Test" task could not be loaded from the assembly C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll. Could not load file or assembly 'file:///C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, and that the assembly and all its dependencies are available.

Tệp này chắc chắn tồn tại, vậy tại sao MSBuild không thể tìm thấy?

Tôi thậm chí đã cố gắng mã hóa cứng "C: \ WIP \ TestSolution" thay cho "$ (SolutionDir)" và nhận được lỗi tương tự. Tuy nhiên, nếu tôi sao chép .dll đó vào máy tính để bàn của tôi và mã hóa đường dẫn đến máy tính để bàn của tôi, nó hoạt động DOES, điều mà tôi không thể hiểu tại sao.

EDIT: Tôi không có đường dẫn sai. Tôi đã sửa đổi các bản dựng Debug/Release cho BuildTasks để xuất ra tệp .dll chỉ với thư mục bin vì tôi không muốn Debug/Release có các đường dẫn khác nhau.

+3

Bạn đã giải quyết được sự cố chưa? Tôi gặp vấn đề tương tự. – sean

+0

3 năm không có độ phân giải? Tôi gặp vấn đề này nhưng bài đăng này không giúp ích một chút vì chưa rõ vấn đề đã được giải quyết ... – DaveN59

Trả lời

2

Slace đã làm đúng. Bạn nhiều hơn khả năng có con đường của bạn để lắp ráp sai. Và nó có lẽ nên được:

<UsingTask 
    TaskName="BuildTasks.Test" 
    AssemblyFile="$(SolutionDir)src\BuildTasks\bin\$(Configuration)\BuildTasks.dll" /> 

<Target Name="AfterBuild"> 
    <Test /> 
</Target> 
+0

@Tinister: Theo chỉnh sửa của bạn ở trên, sử dụng $ (Cấu hình) trong đường dẫn là đúng cách, vì nó sẽ là 'Phát hành' hoặc 'Gỡ lỗi' (hoặc bất kỳ tên nào khác bạn sử dụng) – gregmac

10

Chúng tôi đã cố gắng này và chúng tôi tìm thấy rằng bạn phải đặt UseTask ở đầu tệp dự án (và có tất cả các đường dẫn của bạn ngay). Tuy nhiên một khi thats tại chỗ và nhiệm vụ tải lên nó sẽ chỉ làm việc một lần. Sau đó xây dựng bắt đầu thất bại bởi vì nó không thể sao chép các DLL rằng nhiệm vụ được in Chúng tôi đang thực sự chạy một nhiệm vụ xây dựng bài thats bên trong cùng một lắp ráp/dự án mà chúng tôi đang xây dựng.

Những gì chúng tôi đã làm để giải quyết điều này là khởi chạy một quá trình MSBuild riêng biệt trên một tệp MSBuild riêng biệt để chạy các tác vụ Tạo bài đăng. Bằng cách đó, DLL không được tải cho đến sau khi được xây dựng và sao chép vào thư mục bin.

<Target Name="AfterBuild"> 
    <Exec Command="$(MSBuildBinPath)\MSBuild.exe 
      &quot;$(MSBuildProjectDirectory)\PostBuild.msbuild&quot; 
      /property:SomeProperty=$(SomeProperty)" /> 
</Target> 

Lưu ý rằng bạn có thể chuyển thuộc tính vào tác vụ phụ này trên dòng lệnh.

Và PostBuild.msbuild trông như thế này:

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="PostBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> 
    <UsingTask TaskName="PostBuild" AssemblyFile="$(MSBuildProjectDirectory)\bin\AssemblyThatJustBuiltAndContainsBuildTask.dll" /> 
    <PropertyGroup> 
     <SomeProperty>SomePropertyDefaultValue</SomeProperty> 
    </PropertyGroup> 

    <Target Name="PostBuild"> 
     <MyPostBuildTask SomeProperty="$(SomeProperty)" /> 
    </Target> 
</Project> 
+0

Cảm ơn rất nhiều công trình lớn thời gian cho tôi. – daljit

1

Vô hiệu hóa MSBuild nút tái sử dụng cũng sẽ khắc phục vấn đề này:

  • Trên dòng lệnh MSBuild, vượt qua tùy chọn /nr:false.
  • Đối với Visual Studio, bạn phải đặt biến môi trường MSBUILDDISABLENODEREUSE thành 1 trước khi bắt đầu VS.

Xem Visual Studio 2012 RTM has MSBuild.exe in memory after close

0

Các khóa của nhiệm vụ DLL tùy chỉnh có thể tránh được nếu tất cả các nhiệm vụ tùy chỉnh kế thừa từ AppDomainIsolatedTask và nếu bạn thiết lập các biến môi trường MSBUILDDISABLENODEREUSE = 1 trước khi bắt đầu Visual Studio.

Việc lắp ráp với nhiệm vụ xây dựng tùy chỉnh bị khóa cả bởi devenv.exe và msbuild.exe.

Bạn có thể thực hiện các quá trình msbuild.exe biến mất bằng MSBUILDDISABLENODEREUSE = 1, nhưng devenv.exe sẽ vẫn thỉnh thoảng khóa cụm công việc tùy chỉnh nếu tác vụ tùy chỉnh của bạn được kế thừa từ Task.

Mặt khác, nếu bạn chỉ kế thừa từ AppDomainIsolatedTask và không đặt MSBUILDDISABLENODEREUSE các quá trình MSBuild không hoạt động sẽ vẫn khóa lắp ráp.

+1

Bạn có thể giải thích thêm một chút không? –

+0

Tôi đã mở rộng câu trả lời. – user400144

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