2013-04-28 32 views
8

Tôi đang cố viết công cụ tạo mã. Đối với công cụ này, điều quan trọng là mã được tạo sẵn có trước khi xây dựng (ví dụ: đối với IntelliSense). Tôi biết Visual Studio sẽ ít nhất là một phần đánh giá kế hoạch xây dựng dự án tự động để tạo ra IntelliSense, nhưng tôi không thể tìm thấy nhiều thông tin về các chi tiết.Visual Studio quyết định khi nào và cách xây dựng lại IntelliSense như thế nào?

Ví dụ đơn giản hơn, giả sử tôi muốn lấy tất cả các mục có hành động xây dựng None và biên dịch chúng. Tôi có một dự án như thế này:

<Project [...]> 
    [...] 
    <Compile Include="Foo.cs" /> 
    <None Include="Bar.cs" /> 
</Project> 

Một cách để có được Bar.cs để biên dịch là để thêm dòng sau vào dự án:

<PropertyGroup> 
    <CoreCompileDependsOn> 
    $(CoreCompileDependsOn);IndirectCompile 
    </CoreCompileDependsOn> 
</PropertyGroup> 
<Target Name="IndirectCompile"> 
    <CreateItem Include="@(None)"> 
    <Output ItemName="Compile" TaskParameter="Include" /> 
    </CreateItem> 
</Target> 

Nếu tôi làm theo cách này, Visual Studio đóng vai trò cơ bản giống nhau như thể Bar.cs có hành động Compile để bắt đầu. IntelliSense hoàn toàn có sẵn; nếu tôi thực hiện thay đổi trong Bar.cs, nó được phản ánh ngay lập tức (tốt, ngay lập tức như hoạt động nền bình thường) trong IntelliSense khi tôi đang chỉnh sửa Foo.cs, v.v.

Tuy nhiên, thay vì trực tiếp biên dịch mục nhập None, tôi muốn sao chép nó vào thư mục obj và sau đó biên dịch từ đó. Tôi có thể thực hiện việc này bằng cách thay đổi mục tiêu IndirectCompile thành điều này:

<Target Name="IndirectCompile" 
     Inputs="@(None)" 
     Outputs="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')" 
> 
    <Copy SourceFiles="@(None)" 
     DestinationFiles="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')" 
    > 
    <Output TaskParameter="DestinationFiles" ItemName="Compile" /> 
    </Copy> 
</Target> 

Làm điều này khiến cho IntelliSense ngừng cập nhật. Tác vụ hoạt động trên phân tích xây dựng, phụ thuộc và công việc xây dựng gia tăng, Visual Studio chỉ dừng tự động chạy khi tệp đầu vào được lưu.

Vì vậy, điều đó dẫn đến câu hỏi tiêu đề: Visual Studio chọn chạy mục tiêu hay không cho IntelliSense như thế nào? Tài liệu chính thức duy nhất mà tôi tìm thấy là this, cụ thể là phần "Thiết kế thời gian IntelliSense". Tôi khá chắc chắn mã của tôi đáp ứng tất cả các tiêu chí đó. Tôi đang thiếu gì?

Trả lời

6

Sau một vài ngày thử nghiệm và poking xung quanh trong trình gỡ lỗi tôi nghĩ rằng tôi đã tìm thấy câu trả lời, và tiếc là câu trả lời là điều này là không thể (ít nhất là không theo cách được hỗ trợ rõ ràng - tôi chắc chắn có là cách để lừa hệ thống).

Khi dự án được tải và khi bản thân dự án thay đổi (tệp đã thêm/xóa, xây dựng hành động đã thay đổi, v.v.), bản dựng IntelliSense được thực thi (csproj.dll!CLangCompiler::RunIntellisenseBuild). Bản dựng này sẽ chạy các tác vụ lên đến và bao gồm tác vụ Csc. Csc sẽ không thực thi bình thường, mà thay vào đó chỉ cần nạp lại các đầu vào của nó vào máy chủ của nó (Visual Studio).

Từ thời điểm này trở đi, Visual Studio theo dõi các tệp được cung cấp dưới dạng Sources đến tác vụ Csc. Nó sẽ theo dõi các tệp đó để thay đổi và khi chúng thay đổi, hãy cập nhật IntelliSense. Vì vậy, trong ví dụ của tôi, nếu tôi chỉnh sửa theo cách thủ công Bar.g.cs những thay đổi đó sẽ được chọn. Nhưng các nhiệm vụ xây dựng bản thân sẽ không được chạy lại cho đến khi thay đổi dự án hoặc xây dựng được yêu cầu một cách rõ ràng.

Vì vậy, điều đó thật đáng thất vọng, nhưng không đáng ngạc nhiên, tôi đoán vậy. Nó cũng giải thích một cái gì đó khác tôi đã luôn luôn tự hỏi về - XAML tập tin với một code-đằng sau có xu hướng có một hành động Công cụ Tuỳ chỉnh của MSBuild:Compile, có lẽ vì lý do chính xác này.

Tôi sẽ đánh dấu đây là câu trả lời, nhưng tôi rất muốn được thông báo là tôi đã sai và rằng tôi đã bỏ lỡ điều gì đó.

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