Zdarzenie wstępne dla całego rozwiązania?

Mam rozwiązanie w Visual Studio, które zawiera kilka projektów. Chciałbym uruchomić polecenie na samym początku każdej kompilacji - bez względu na to, które projekty są zaangażowane i czy są aktualne.

Zasadniczo potrzebuję czegoś podobnego do zdarzenia pre-build dla całego rozwiązania, ale niestety VS nie wydaje się je wspierać. Czy ktoś zna alternatywny sposób na osiągnięcie tego, czego potrzebuję?

Author: Andreas Niedermair, 2010-02-19

6 answers

Nietypowe wymagania. Ale da się to zrobić. Dodaj nowy projekt do rozwiązania, użyj Visual C++ > ogólne > Makefile szablon projektu. Ustaw jego ustawienie linii poleceń NMAKE > Build na polecenia, które chcesz wykonać. Użyj Project > Project Dependencies, aby uzależnić od niego wszystkie inne projekty.

 41
Author: Hans Passant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-07 22:18:10

Krótki przegląd moich wariantów poniżej

tylko uwaga: jest to niekompletna lista wszystkich istniejących (patrz również inne odpowiedzi itp.), Popieram tylko moje oryginalne sztuczki w stanie faktycznym...

podsumowanie

Uwagi:

  • 1 - nie wymaga żadnych dodatkowych rozszerzeń. Ale może działać tylko na poziomie projektów, więc używamy go do naśladowania naszego poziomu rozwiązania... Jest trudne i niewygodne dla wspólnego rozwiązania, ale jest wariant. Patrz poniżej.
  • 2 - oryginalny silnik vsSolutionBuildEvent zapewnia kilka sposobów ujednoliconej obsługi VS i msbuild.exe. Prosty sposób na wywołanie after.<name>.sln.targets dostępne tylko dla msbuild.exe (nie wymaga to dodatkowych kroków, po prostu działania). Ale tylko oryginalny silnik (inc. vsCommandEvent) może pozwolić na Dodatkowe skrypty, które obsługują na przykład (7zip archiver, pakowanie pakietu nuget bez nuget.exe, zdalne serwery itp.). Jednak nie jest to ważne dla naszego pytania/problemu i możesz użyć dowolnej dostępnej opcji, aby wesprzeć poziom rozwiązania, jeśli widzisz + powyżej.

Wariant 1: Microsoft.VisualStudio.Shell.Interop

Ten wariant nie jest dla prostych użytkowników VS. jednak może być przydatny dla kompletnego rozwiązania itp.

Należy zaimplementować, na przykład:

Np:

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

Następnie zarejestruj handler z metodami' advice ' jako priorytetowy słuchacz, tzn. dla IVsUpdateSolutionEvents2 powinieneś użyć AdviseUpdateSolutionEvents

Jest ważne , ponieważ BuildEvents (zobacz EnvDTE) - prawdopodobnie nie pomoże i może działać za późno- przykład

Próbka z 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);

gdzie:

  • Pole sbm powinno być częścią klasy ochrony przed GC.
  • Aby uzyskać usługę SVsSolutionBuildManager jest używany ServiceProvider, ale może być tak, jak potrzebujesz. Zobacz msdn

Teraz możemy pracować ze wszystkimi projektami jednocześnie-na poziomie rozwiązania.

Wariant 2: Cele i mapa projektów.

Ok, kochasz coś takiego - MSBuild: Rozszerzenie solution build , ale ten wariant może działać z procesami build z msbuild.exe a nie z VS IDE...

Ale VS używa również celów (Build, Rebuild, Clean, ..) w plikach projektu (*.csproj,*.vcxproj,.) po rozpoczęciu budowy. Więc możemy również spróbować tego, ale pamiętaj:

  • VS jest również ignoruje niesamowite .plik sln. Tworzy wszystkie cele końcowe z załadowanego środowiska z EnvDTE itp.
  • The .sln powinien być przetwarzany przez msbuild.exe tylko jako: automatycznie Generuj .metaproj (domyślnie w pamięci), który zawiera 'co i kiedy' zostanie zbudowany. W tym wspólne cele dla wszystkich projektów, jeśli istnieją, na przykład:
...
<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" />
  • i tak .metaproj również nie może być oglądany przez VS IDE.

Dlatego do pracy ze wspólnymi celami z VS IDE można używać tylko plików projektu z pewnymi ograniczeniami(bez modyfikacji/rozszerzenia VS, to znaczy).

I tak, jeśli potrzebujesz wspólne rozwiązanie (np. możesz nie wiedzieć o projektach itp. - Może to być na przykład dla niektórych rozwiązań pudełkowych i podobnych):

  • Dodaj swój wspólny .pliki docelowe do wszystkich projektów (może to być automatycznie za pomocą dowolnego narzędzia, inc. NuGet events itd.), na przykład: <Import Project="..\<SolutionFile>.targets" />
  • następnie należy użyć pewnych ograniczeń dla:
    • "tylko-przed wszystkimi projektami"
    • "tylko-przecież wszystkie projekty"

I dla przykład, tak, może to być "Mapa projektów": {]}

    W przeciwieństwie do innych projektów, które nie są w pełni kompatybilne z Visual Studio 2000, nie są w pełni kompatybilne z Visual Studio 2000, ale są w pełni kompatybilne z Visual Studio 2000 i Visual Studio 2000.]}
...
<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>
...

Ogólnie rzecz biorąc, będziemy używać mapy projektów i teraz wiemy "co i kiedy" powinno się wydarzyć. Jest bezpieczny dla wszystkich lub większości przypadków(zmiany kolejności budowy lub usunięcie dowolnych projektów z rozwiązania). Jednak! powinieneś zarządzać sekcją <Import> dla nowych projektów w pierwszy init. Jest to naprawdę niewygodne, ale jest również wariant...

Variant 3: Plugin vsSolutionBuildEvent

Dziś jest to najbardziej kompletne rozwiązanie do pracy z wieloma wydarzeniami jako Events-Catcher z wieloma zaawansowanymi działaniami do utrzymania projektów i bibliotek, budowania procesów i procesów w czasie wykonywania z Visual Studio i narzędzia MSBuild.

Różne typy akcji dla wszystkich podprojektów jednocześnie w rozwiązaniu jako rozwiązanie-zdarzenia lub indywidualnie dla każdego.

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

plugin-vsSolutionBuildEvent

Jak to działa w środku

Jeśli chcesz użyć wariant 1 powyżej lub chcesz zobaczyć jak pracować z powłoką.Interop, EnvDTE, IVsUpdateSolutionEvents2, MSBuild Engine itp. zobacz tutaj :

program

Wariant 4. EnvDTE.CommandEvents

to variant nie jest również dla prostych użytkowników VS. jednak, co do Variant 1 {[23] } może być przydatny dla Twojego rozwiązania box itp.

To nie to samo, ale tak, jest to również możliwe z EnvDTE.CommandEvents jak w Variant 1 powyżej.

Powinieneś już wiedzieć (patrz wyżej) o To rozwiązanie dla priorytetowej pracy z bieżącym typem akcji build... Dlaczego więc nie użyć tego jako podstawowego rozwiązania dla obecnego problemu ?

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

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

};

Gdzie: 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/

Co więcej, opcjonalnie możesz wyłączyć te polecenia, jeśli zajdzie taka potrzeba. w poniższym wariancie zobaczysz kompletne rozwiązanie w ten sposób.

Wariant 5. Plugin vsCommandEvent

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

Prezentuje również zaawansowany sposób obsługi większości zdarzeń, ale w przeciwieństwie do pierwszy specjalizował się w MS Visual Studio do zaawansowanej pracy ze wszystkimi poleceniami i danymi wyjściowymi jako menedżer tego. Nie tylko dla projektów i rozwiązań, ale także dla całego Visual Studio IDE.

Ogólnie rzecz biorąc, jest to powszechne rozwiązanie wariant 4 i możesz po prostu nadpisać wszystkie powyższe polecenia, aby rozwiązać ten problem.

i dla tego samego modelu Event-Actions jak w vssolutionbuildevent może być przydatny dla większości sprawy.

program

"Pomóż mi z wariantami"

Istnieje otwarta implementacja dla wszystkich tych wariantów. Zobacz tutaj i uśmiechnij się :

 40
Author: reg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:41

Możesz rzucić okiem na ten artykuł: MSBuild: rozszerzenie kompilacji rozwiązań.

Wydaje się być dokładnie tym, czego potrzebujesz.

 17
Author: Andriy K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-19 17:49:38

Robimy to przez dodanie pustego projektu i ustawienie zdarzeń budowania dla tego projektu. Następnie musisz dać każdemu projektowi zależność od tego pustego projektu, aby upewnić się, że jest budowany za każdym razem.

 9
Author: erelender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-19 10:24:35

Minęło trochę czasu i niektóre rzeczy w infrastrukturze. Net zmieniły się od tego czasu, dając nowe opcje. Teraz moim wyborem do rozwiązania tego króla problemu są pakiety nuget. Moje kroki budowania umieszczam w pakiecie, który następnie jest dołączany do każdego projektu. Z pomocą Visual Studio package manager daje przegląd pakietów na poziomie rozwiązania, więc bardzo łatwo jest sprawdzić tę regułę.

 0
Author: Andriy K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 18:30:21

Kolejny stary post, ale zainspirowany rozwiązaniem @ reg chciałem uruchomić prosty build timer, który zapisywałby czas, jaki upłynął do budowania rozwiązania. Zdarzenia kompilacji działają przy użyciu modułu powershell, który Ładuję za pomocą konsoli Menedżera pakietów, gdy uruchomi się Visual Studio IDE.

Więc utwórz moduł powershell jak BuildEvents.psm1:

<#
.SYNOPSIS
    Register solution build events

.DESCRIPTION
    Registers the OnBuildBegin and OnBuildDone events for the entire solution
    De-registers the events if called multiple times.

.EXAMPLE
    RegisterBuildEvents
#>
function RegisterBuildEvents{
  try {
    Unregister-Event -SourceIdentifier "OnBuildBegin" -Force
  } catch {
    #we don't care if this doesn't work
  }
  try {
    Unregister-Event -SourceIdentifier "OnBuildDone" -Force
  } catch {
    #we don't care if this doesn't work
  }
  $obj = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($dte.Application.Events.BuildEvents, [EnvDTE.BuildEventsClass])
  Register-ObjectEvent -InputObject $obj -EventName OnBuildBegin -Action {
    # do stuff here on build begin
    Write-Host "Solution build started!"
  } -SourceIdentifier "OnBuildBegin"
  Register-ObjectEvent -InputObject $obj -EventName OnBuildDone -Action {
    # do stuff here on build done
    Write-Host "Solution build done!" 
  } -SourceIdentifier "OnBuildDone"
}

# export the functions from the module
export-modulemember -function RegisterBuildEvents

Importuj moduł, gdy host menedżera pakietów inicjalizuje się:

  1. w konsoli Menedżera pakietów wpisz $profile, aby uzyskać lokalizację Twój profil powershell
  2. przejdź do tego katalogu na dysku, jeśli nie ma tam pliku Utwórz o nazwie zwracanej przez powyższe polecenie (np. NuGet_profile.ps1)
  3. Otwórz plik w notatniku i dodaj następujące linie

    Import-Module -Name <Path to your ps module>\BuildEvents -Force
    RegisterBuildEvents
    
 0
Author: James Close,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 09:39:36