Я заметил, что, когда я запускаю 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:
- трогает inpu t file
- Распечатывает свою метку
- Создает проект либо с помощью 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
. Кто-нибудь знает что-нибудь об этом?
Может быть, VS необходимо сделать фоном, чтобы получить информацию Intellisense? Вы можете попробовать вставить директиву = false в ваши .csproj-файлы и посмотреть, не приведет ли это к тем характеристикам, которые вам больше нравятся. http://stackoverflow.com/a/646153/253938 –
RenniePet
Пробовал. Никакого эффекта. – mark