IT Share you

솔루션 전체의 사전 구축 이벤트?

shareyou 2020. 11. 21. 08:43
반응형

솔루션 전체의 사전 구축 이벤트?


여러 프로젝트를 포함하는 Visual Studio에 솔루션이 있습니다. 어떤 프로젝트가 관련되어 있는지 여부와 관계없이 모든 빌드의 맨 처음에 명령을 실행하고 싶습니다.

본질적으로 솔루션 전체의 사전 빌드 이벤트와 유사한 것이 필요하지만 불행히도 VS는이를 지원하지 않는 것 같습니다. 누구든지 내가 필요한 것을 달성하는 다른 방법을 알고 있습니까?


비정상적인 요구 사항. 하지만 할 수 있습니다. 솔루션에 새 프로젝트를 추가하고 Visual C ++> 일반> Makefile 프로젝트 템플릿을 사용합니다. NMake> Build Command Line 설정을 실행하려는 명령으로 설정합니다. 프로젝트> 프로젝트 종속성을 사용하여 다른 모든 프로젝트가 종속되도록합니다.


아래 내 변형에 대한 간략한 개요

참고 사항 : 기존의 모든 목록이 불완전합니다 (다른 답변 등도 참조하십시오), 실제 상태에서 원래 트릭 만 지원합니다 ...

요약

메모:

  • 1- 추가 확장이 필요하지 않습니다. 하지만 프로젝트 수준에서만 작동 할 수 있으므로 솔루션 수준을 에뮬레이션하는 데 사용합니다. 일반적인 솔루션에는 어렵고 불편하지만 변형입니다. 아래를 참조하십시오.
  • 2 -vsSolutionBuildEvent의 원래 엔진은 VS 및 msbuild.exe에 대한 몇 가지 통합 지원을 제공합니다. msbuild.exe에서만 사용할 수있는를 targets mode호출 하는 간단한 방법입니다 after.<name>.sln.targets(추가 단계가 필요하지 않고 단순히 작업 만 수행하면 됨). 그러나 원래 엔진 (vsCommandEvent 포함)만이 예를 들어 지원하는 추가 스크립팅을 허용 할 수 있습니다 (7zip 아카이버, nuget.exe없이 nuget 패키지 압축, 원격 서버 등). 그러나 질문 / 문제에는 중요하지 않으며 +위에 표시된 경우 솔루션 수준을 지원하기 위해 사용 가능한 옵션을 사용할 수 있습니다 .

변형 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를 아마하지 않습니다 도움을 너무 늦게 작동 할 수 - -)

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 : 프로젝트의 대상 및지도.

좋아, 당신은 다음과 같은 것을 좋아합니다 -MSBuild : 솔루션 빌드 확장 ,하지만이 변종은 VS IDE가 아닌 msbuild.exe의 빌드 프로세스에서 작동 할 수 있습니다 ...

그러나 VS는 빌드 작업이 시작될 때 프로젝트 파일 (* .csproj, * .vcxproj, ..)에서 대상 (Build, Rebuild, Clean, ..)도 사용합니다. 그래서 우리는 이것을 시도 할 수도 있지만 기억하세요 :

  • 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" />
  • 그런 다음 다음에 대해 몇 가지 제한을 사용해야합니다.
    • "만-모든 프로젝트 이전"
    • "만-모든 프로젝트 이후"

예를 들어, '프로젝트지도'가 될 수 있습니다.

  • '프로젝트의지도' (VS IDE에서 차 예) 비주얼 스튜디오 IDE에서 빌드 작업을위한 솔루션 전체 PRE / POST '이벤트를'보여
...
<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>첫 번째 초기화에서 새 프로젝트에 대한 섹션을 관리해야 합니다. 이것은 정말 불편하지만 변형입니다 ...

변형 3 : 플러그인 vsSolutionBuildEvent

현재는 프로젝트 및 라이브러리 유지 관리, Visual Studio 및 MSBuild 도구에서 런타임시 프로세스 및 프로세스 구축을위한 다양한 고급 작업이 포함 된 Events-Catcher와 같은 많은 이벤트 작업을위한 가장 완벽한 솔루션입니다.

솔루션의 모든 하위 프로젝트에 대해 솔루션 이벤트로 한 번에 또는 각각에 대해 개별적으로 다른 작업 유형.

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

플러그인-vsSolutionBuildEvent

내부 작동 방식

Variant 1 을 사용 하거나 Shell.Interop, EnvDTE, IVsUpdateSolutionEvents2, MSBuild Engine 등으로 작업하는 방법을 확인하려면 여기를 참조 하십시오 .

계획

변형 4. EnvDTE.CommandEvents

이 변형은 VS의 단순한 사용자에게도 적합하지 않습니다. 그러나 변형 1의 경우 상자 솔루션 등에 유용 할 수 있습니다.

동일하지는 않지만 예, 위의 변형 1 과 같이 EnvDTE.CommandEvents 에서도 가능합니다 .

You should already know (see above) about this solution for priority work with current type of the build action... So why not to use this as primary solution for current problem ?

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

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

};

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

Moreover, optional you can suppress this commands if you need. In variant below you will see the complete solution for this way.

Variant 5. Plugin vsCommandEvent

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

It also presents advanced handler of most events, but unlike the first it specialized for MS Visual Studio for advanced work with all commands and output data as manager of this. Not only for projects and solutions, but also for the whole Visual studio IDE.

In general, it is the common solution of Variant 4 and you can simply override all commands above to solve this problem.

And for the same Event-Actions model like in vsSolutionBuildEvent it can be useful for most cases.

계획

"Help me with variants"

There are open implementation for all these variants. See here and smile:


You can take a look on this article: MSBuild: Extending the solution build.

Seems to be exactly what you need.


We do this by adding an empty project and setting build events for this project. Then you have to give each project dependency to this empty project to make sure that it gets built everytime.


It's been a while, and some things in .Net infrastructure changed since, giving new options. Now my choice for solving this king of problem are nuget packages. I put my build steps into package which then included into every single project. Helpfully, Visual Studio package manager gives overview of packages on solution level, so it's pretty easy to check this rule.


Another old post but inspired by @reg solution I wanted to run a simple build timer that would log the elapsed time for a solution build. I got the build events working using a powershell module which I load via the package manager console when the Visual Studio IDE starts.

So create a powershell module like 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

Import the module when the Package Manager host initialises:

  1. In the package manager console type $profile to get the location of your powershell profile
  2. 디스크에 해당 디렉토리 검색, 어떤 파일이없는 경우 위의 명령에 의해 반환 된 이름으로 하나가 생성 (예를 들어 NuGet_profile.ps1)
  3. 메모장에서 파일을 열고 다음 줄을 추가하십시오.

    Import-Module -Name <Path to your ps module>\BuildEvents -Force
    RegisterBuildEvents
    

참고 URL : https://stackoverflow.com/questions/2295454/solution-wide-pre-build-event

반응형