2014-11-26 2 views
0

Я заметил, что, когда я запускаю devenv в командной строке, он выполняет сборку фона перед тем, как перейти к первому. У меня есть сильное подозрение, что что-то ужасно неправильно с моей средой.Как предотвратить devenv от вызова цели компиляции в фоновом режиме?

Пожалуйста, соблюдайте:

PS C:\work\a> dir 


    Directory: C:\work\a 


Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
d----  11/26/2014 12:40 AM   .hg 
-a---  11/25/2014 11:48 PM   87 .hgignore 
-a---  11/26/2014 12:39 AM  264 1.ps1 
-a---  11/26/2014 12:38 AM  1594 a.csproj 
-a---  11/26/2014 12:43 AM   2 in.txt 


PS C:\work\a> 

Где

1.ps1

param([switch]$msbuild) 

$in="in.txt" 
(dir $in).LastWriteTime = Get-Date 
dir $in |% { $_.Name + " : " + $_.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss.ffffff") } 
if ($msbuild) 
{ 
    msbuild .\a.csproj /v:m 
} 
else 
{ 
    devenv .\a.csproj /build Debug /SafeMode 
} 

Это простой скрипт, который PowerShell:

  1. трогает inpu t file
  2. Распечатывает свою метку
  3. Создает проект либо с помощью msbuild, либо с командной строки devenv.

a.csproj

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> 
    <PropertyGroup> 
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> 
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> 
    <ProjectGuid>{EB5EB1C9-DC39-4E48-875B-094CBC0F468A}</ProjectGuid> 
    <ProjectTypeGuids>{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> 
    <OutputType>Library</OutputType> 
    <AppDesignerFolder>Properties</AppDesignerFolder> 
    <RootNamespace>a</RootNamespace> 
    <AssemblyName>a</AssemblyName> 
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> 
    <FileAlignment>512</FileAlignment> 
    <TargetFrameworkProfile /> 
    <OldToolsVersion>2.0</OldToolsVersion> 
    <OutputPath>bin\$(Configuration)</OutputPath> 
    </PropertyGroup> 
    <ItemGroup> 
    <None Include="in.txt" /> 
    </ItemGroup> 
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
    <PropertyGroup> 
    <CompileDependsOn>$(CompileDependsOn);MyTarget</CompileDependsOn> 
    </PropertyGroup> 
    <Target Name="A" BeforeTargets="_CheckForInvalidConfigurationAndPlatform" Condition="Exists('out.txt')"> 
    <ItemGroup> 
     <Out Include="out.txt"/> 
    </ItemGroup> 
    <Message Text="%(Out.Identity) : %(Out.ModifiedTime)" Importance="High" /> 
    </Target> 
    <Target Name="MyTarget" Inputs="in.txt" Outputs="out.txt"> 
    <Message Text="Touching now ..." Importance="High" /> 
    <Touch Files="out.txt" AlwaysCreate="true" /> 
    </Target> 
</Project> 

Как вы можете видеть, что это тривиальное C# проект без исходного кода на всех. Он:

  • впрыскивает MyTarget цели в CompileDependsOn список.
  • Выводит отметку времени входного файла (in.txt) перед запуском любых связанных с сборкой целей.
  • Если входной файл новее, чем выходной файл (out.txt), то MyTarget запускается и выводит сообщение и прикасается выходной файл

Теперь вот что происходит, когда я запускаю сценарий, требующий Devenv командной строки сборки:

PS C:\work\a> .\1.ps1 
in.txt : 2014-11-26 00:44:09.078676 

Microsoft (R) Microsoft Visual Studio 2012 Version 11.0.61030.0. 
Copyright (C) Microsoft Corp. All rights reserved. 
1>------ Build started: Project: a, Configuration: Debug Any CPU ------ 
1> out.txt : 2014-11-26 00:44:09.7744589 
1> a -> C:\work\a\bin\Debug\a.dll 
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 
PS C:\work\a> 

Обратите внимание, что нет «Прикосновение теперь ...» отображается сообщение, но метка времени выходного файла (2014-11-26 00: 44: 09.7744589) уже новее, чем входного файла (2014-11-26 00: 44: 09.078676), и это ПЕРЕД запускается самая первая цель сборки !!! В самом деле, когда я строю уровень диагностической многословия, он говорит мне, что выходы соответствуют последним по отношению к входам !!!

Теперь посмотрим, что происходит, когда я строю с MSBuild:

PS C:\work\a> .\1.ps1 -msbuild 
in.txt : 2014-11-26 00:44:15.854564 
Microsoft (R) Build Engine version 4.0.30319.34209 
[Microsoft .NET Framework, version 4.0.30319.34209] 
Copyright (C) Microsoft Corporation. All rights reserved. 

    out.txt : 2014-11-26 00:44:09.7744589 
    Touching now ... 
    a -> C:\work\a\bin\Debug\a.dll 
PS C:\work\a> 

Все как и ожидалось - выходной файл временной метки (2014-11-26 00: 44: 09,7744589) старше, чем входной файл (2014-11-26 00: 44: 15,854564). Итак, печатается сообщение «Touching now ...».

Обратите внимание, что я запускаю devenv в безопасном режиме. Я использую VS2012.

Пожалуйста, помогите мне понять, что происходит.

EDIT 1

Hooking в CoreBuildDependsOn дает ожидаемые результаты:

<CoreBuildDependsOn>$(CoreBuildDependsOn);MyTarget</CoreBuildDependsOn> 

И результат:

PS C:\work\a> .\1.ps1 
in.txt : 2014-11-26 12:55:56.787793 

Microsoft (R) Microsoft Visual Studio 2012 Version 11.0.61030.0. 
Copyright (C) Microsoft Corp. All rights reserved. 
1>------ Build started: Project: a, Configuration: Debug Any CPU ------ 
1> out.txt : 2014-11-26 12:54:29.8173007 
1> a -> C:\work\a\bin\Debug\a.dll 
1> Touching now ... 
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 
PS C:\work\a> 

Обратите внимание на "Прикосновение теперь ..." сообщение и отметка out.txt перед сборкой старше, чем in.txt - как и ожидалось.

Вывод: цель Compile мишенью вызывается молчанием devenv в фоновом режиме, но не CoreBuild. Кто-нибудь знает что-нибудь об этом?

+0

Может быть, VS необходимо сделать фоном, чтобы получить информацию Intellisense? Вы можете попробовать вставить директиву = false в ваши .csproj-файлы и посмотреть, не приведет ли это к тем характеристикам, которые вам больше нравятся. http://stackoverflow.com/a/646153/253938 – RenniePet

+0

Пробовал. Никакого эффекта. – mark

ответ

1

Нашел - https://social.msdn.microsoft.com/Forums/en-US/bf86d834-0e48-42ff-b2e4-5f930597bef0/background-compilation-in-visual-c?forum=csharpide

Итак, ответ мы не можем предотвратить фоновую компиляцию, но наши пользовательские компиляции цели могут быть написаны оборонительно путем тестирования BuildingProject собственности. Или так кажется, потому что я на самом деле не тестировал его, поэтому логика в зависимости от CoreBuild кажется мне достаточно хорошей.

Смежные вопросы