Подтвердить что ты не робот

Решение для предварительной сборки?

У меня есть решение в Visual Studio, которое содержит несколько проектов. Я бы хотел запустить команду в самом начале каждой сборки - независимо от того, какие проекты задействованы и независимо от того, обновлены ли они.

По сути, мне нужно что-то похожее на событие предварительной сборки для решения, но, к сожалению, VS, похоже, не поддерживает их. Кто-нибудь знает альтернативный способ достижения того, что мне нужно?

4b9b3361

Ответ 1

Необычное требование. Но это может быть сделано. Добавьте новый проект в свое решение, используйте шаблон Visual С++ > General > Makefile Project. Задайте для своей команды NMake > Build Command Line команды, которые вы хотите выполнить. Используйте Project > Project Dependencies, чтобы все другие проекты зависели от него.

Ответ 2

Краткий обзор моих вариантов ниже

просто примечание: это неполный список всех существующих (см. также другие ответы и т.д.), я поддерживаю только свои оригинальные трюки в реальном состоянии...

summary

Примечания:

  • 1 - не требует никаких дополнительных расширений. Но это может работать только на уровне проектов, поэтому мы используем его для эмуляции нашего уровня решения... Это сложно и неудобно для общего решения, но вариант. См. Ниже.
  • 2 - Исходный движок vsSolutionBuildEvent предоставляет несколько способов унифицированной поддержки VS и msbuild.exe. Простым способом targets mode вызывать after.<name>.sln.targets, который доступен только для msbuild.exe(для этого не требуются дополнительные шаги, просто действие). Но только оригинальный движок (в том числе vsCommandEvent) может допускать дополнительные скрипты, которые поддерживаются, например, (архивирование 7zip, упаковка пакета nuget без nuget.exe, удаленные серверы и т.д.). Однако это не важно для нашего вопроса/проблемы, и вы можете использовать любую доступную опцию для поддержки уровня решения, если вы видите + выше.

Вариант 1: Microsoft.VisualStudio.Shell.Interop

Этот вариант не для простых пользователей VS. Однако это может быть полезно для вашего полного решения и т.д.

Вы должны реализовать, например:

например:

public sealed class YourPackage: Package, IVsSolutionEvents, IVsUpdateSolutionEvents2
{
...
    public int UpdateSolution_Begin(ref int pfCancelUpdate)
    {
        //TODO:
    }
}

Затем обработчик регистра с помощью методов "Рекомендовать" в качестве приоритетного прослушивателя, то есть для IVsUpdateSolutionEvents2 вы должны использовать AdviseUpdateSolutionEvents

Важно, потому что BuildEvents (см. EnvDTE) - вероятно, не поможет и может работать слишком поздно - Пример p >

Пример с AdviseUpdateSolutionEvents:

// http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivssolutionbuildmanager2.aspx
private IVsSolutionBuildManager2 sbm;

// http://msdn.microsoft.com/en-us/library/bb141335.aspx
private uint _sbmCookie;
...

sbm = (IVsSolutionBuildManager2)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager));
sbm.AdviseUpdateSolutionEvents(this, out _sbmCookie);

Где:

  • поле sbm должно быть как часть класса для защиты от GC.
  • чтобы получить сервис SVsSolutionBuildManager, используется ServiceProvider, но он может быть как вам нужно. См. Msdn

Теперь мы можем работать со всеми проектами сразу - на уровне решения.

Вариант 2: Цели и Карта проектов.

ok, вам нравится что-то вроде этого - MSBuild: расширение сборки решения, но этот вариант может работать с процессами сборки из msbuild.exe, а не из VS IDE...

Но VS также использует цели (Build, Rebuild, Clean,..) в файлах проекта (*.csproj, *.vcxproj,..) при запуске операций сборки. Поэтому мы также можем попробовать это, но помните:

  • VS также игнорирует удивительный файл .sln. Он формирует все конечные объекты из загруженной среды с помощью EnvDTE и т.д.
  • .sln должен обрабатываться msbuild.exe только как: автоматически генерировать .metaproj(по умолчанию в памяти), который содержит "что и когда" будет построен. Включая общие цели для всех проектов, если они существуют, например:
...
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter\*" Condition="'$(ImportByWildcardBeforeSolution)' != 'false' and exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter')" />
<Import Project="D:\tmp\p\after.name.sln.targets" Condition="exists('D:\tmp\p\after.name.sln.targets')" />
<Target Name="Build" />
<Target Name="Rebuild" />
<Target Name="Clean" />
<Target Name="Publish" />
  • И да,.metaproj также не может быть просмотрен VS IDE.

Поэтому для работы с общими целями из VS IDE вы можете использовать только файлы проекта с некоторым ограничением (без изменения/расширения VS, это означает).

Итак, если вам нужно общее решение (т.е. вы можете не знать о проектах и ​​т.д.), это может быть, например, для некоторых оконных решений и подобных):

  • Добавьте свой общий файл .targets во все ваши проекты (он может быть автоматически с любым инструментом, включая события NuGet и т.д.)., например: <Import Project="..\<SolutionFile>.targets" />
  • Затем вы должны использовать некоторые ограничения для:
    • "только - перед всеми проектами"
    • "только после всех проектов

И, например, да, это может быть "Карта проектов":

  • 'Map of projects' иллюстрирует все события PRE/POST для всего решения для операций сборки из Visual Studio IDE (т.е. первичный из VS IDE)
...
<Target Name="_Build" BeforeTargets="Build" DependsOnTargets="ProjectsMap">
    <CallTarget Targets="_BuildPRE" Condition="$(ScopeDetectFirst)" />
    <CallTarget Targets="_BuildPOST" Condition="$(ScopeDetectLast)" />
</Target>
<Target Name="_BuildPRE">
    <!-- ... -->
</Target>
<Target Name="_BuildPOST">
    <!-- ... -->
</Target>
...

В общем, мы будем использовать карту проектов, и теперь мы знаем, "что и когда" должно произойти. Он безопасен для всех или большинства случаев (изменения порядка сборки или удаление любых проектов из решения). Однако! вы должны управлять секцией <Import> для новых проектов в первом init. Это действительно неудобно, но также вариант...

Вариант 3: Плагин vsSolutionBuildEvent

Сегодня это наиболее полное решение для работы с множеством событий как Event-Catcher с различными расширенными действиями для поддержки ваших проектов и библиотек, создания процессов и процессов во время выполнения из вашей Visual Studio и MSBuild Tool.

Различные типы действий для всех подпроектов одновременно в решении как решения-события или индивидуально для каждого.

https://visualstudiogallery.msdn.microsoft.com/0d1dbfd7-ed8a-40af-ae39-281bfeca2334/

plugin - vsSolutionBuildEvent

Как это работает внутри

Если вы хотите использовать Вариант 1 выше или вам нужно посмотреть, как работать с Shell.Interop, EnvDTE, IVsUpdateSolutionEvents2, MSBuild Engine и т.д., см. здесь:

scheme

Вариант 4. EnvDTE.CommandEvents

Этот вариант также не для простых пользователей VS. Однако, что касается Вариант 1, это может быть полезно для вашего box-решения и т.д.

Это не одно и то же, но да, это также возможно с EnvDTE.CommandEvents, как в Вариант 1 выше.

Вы уже должны знать (см. выше) о этом решении для приоритетной работы с текущим типом действия сборки... Так почему бы не использовать это в качестве основного решения для текущей проблемы?

_cmdEvents.BeforeExecute += (string guid, int id, object customIn, object customOut, ref bool cancelDefault) => {

    if(UnifiedTypes.Build.VSCommand.existsById(id)) {
        // ... your action
    }

};

Где: Description | guid | id |In |Out| --------------------------|---------------------------------------|-----|---|---| Started: Build Solution |{5EFC7975-14BC-11CF-9B2B-00AA00573819} | 882 | | | Started: Rebuild Solution |{5EFC7975-14BC-11CF-9B2B-00AA00573819} | 883 | | | Started: Clean Solution |{5EFC7975-14BC-11CF-9B2B-00AA00573819} | 885 | | |

http://vsce.r-eg.net/doc/Features/Solution-wide/

Кроме того, необязательно, вы можете подавить эти команды, если вам нужно. В следующем варианте вы увидите полное решение для этого пути.

Вариант 5. Плагин vsCommandEvent

https://visualstudiogallery.msdn.microsoft.com/ad9f19b2-04c0-46fe-9637-9a52ce4ca661/

Он также представляет собой расширенный обработчик большинства событий, но в отличие от первого он специализируется на MS Visual Studio для расширенной работы со всеми командами и выходными данными в качестве менеджера этого. Не только для проектов и решений, но и для всей Visual Studio IDE.

В общем, это общее решение Вариант 4, и вы можете просто переопределить все приведенные выше команды для решения этой проблемы.

И для той же модели Event-Actions, что и в vsSolutionBuildEvent, может быть полезно в большинстве случаев.

scheme

"Помогите мне с вариантами"

Есть открытая реализация для всех этих вариантов. Смотрите здесь и улыбайтесь:

Ответ 4

Мы делаем это, добавляя пустой проект и устанавливаем события сборки для этого проекта. Затем вы должны дать каждому проекту зависимость от этого пустого проекта, чтобы убедиться, что он создается каждый раз.