프로젝트 업그레이드
한 버전의 Visual Studio에서 다음 버전으로 프로젝트 모델을 변경하려면 최신 버전에서 실행할 수 있도록 프로젝트와 솔루션을 업그레이드해야 할 수 있습니다. Visual Studio SDK는 자체 프로젝트에서 업그레이드 지원을 구현하는 데 사용할 수 있는 인터페이스를 제공합니다.
업그레이드 전략
업그레이드를 지원하려면 프로젝트 시스템 구현에서 업그레이드 전략을 정의하고 구현해야 합니다. 전략을 결정할 때 SxS(병렬) 백업, 복사 백업 또는 둘 다를 지원하도록 선택할 수 있습니다.
SxS 백업은 프로젝트에서 업그레이드가 필요한 파일만 복사하고 적절한 파일 이름 접미사(예: ".old")를 추가한다는 의미입니다.
복사 백업은 프로젝트가 모든 프로젝트 항목을 사용자가 제공한 백업 위치에 복사한다는 의미입니다. 그런 다음, 원래 프로젝트 위치의 관련 파일이 업그레이드됩니다.
업그레이드 작동 방식
이전 버전의 Visual Studio에서 만든 솔루션이 최신 버전에서 열리면 IDE는 솔루션 파일을 확인하여 업그레이드가 필요한지 여부를 결정합니다. 업그레이드가 필요하면 업그레이드 마법사가 자동으로 시작되어 사용자에게 업그레이드 프로세스를 안내합니다.
솔루션을 업그레이드해야 하는 경우 각 프로젝트 팩터리에 업그레이드 전략을 쿼리합니다. 전략은 프로젝트 팩터리가 복사 백업 또는 SxS 백업을 지원하는지 여부를 결정합니다. 정보는 백업에 필요한 정보를 수집하고 적용 가능한 옵션을 사용자에게 제공하는 업그레이드 마법사로 전송됩니다.
다중 프로젝트 솔루션
솔루션에 여러 프로젝트가 포함되어 있고 업그레이드 전략이 서로 다른 경우(예: SxS 백업만 지원하는 C++ 프로젝트 및 복사 백업만 지원하는 웹 프로젝트) 프로젝트 팩터리가 업그레이드 전략을 협상해야 합니다.
솔루션은 각 프로젝트 팩터리에서 IVsProjectUpgradeViaFactory를 쿼리합니다. 그런 다음, UpgradeProject_CheckOnly를 호출하여 글로벌 프로젝트 파일을 업그레이드해야 하는지 확인하고 지원되는 업그레이드 전략을 결정합니다. 그런 다음, 업그레이드 마법사가 호출됩니다.
사용자가 마법사를 완료하면 각 프로젝트 팩터리에서 UpgradeProject가 호출되어 실제 업그레이드가 수행됩니다. 백업을 용이하게 하기 위해 IVsProjectUpgradeViaFactory 메서드는 업그레이드 프로세스의 세부 정보를 기록하는 SVsUpgradeLogger 서비스를 제공합니다. 이 서비스는 캐시할 수 없습니다.
모든 관련 전역 파일을 업데이트한 후 각 프로젝트 팩터리는 프로젝트를 인스턴스화하도록 선택할 수 있습니다. 프로젝트 구현은 IVsProjectUpgrade를 지원해야 합니다. 그런 다음, UpgradeProject 메서드를 호출하여 모든 관련 프로젝트 항목을 업그레이드합니다.
참고 항목
UpgradeProject 메서드는 SVsUpgradeLogger 서비스를 제공하지 않습니다. 이 서비스는 QueryService를 호출하여 가져올 수 있습니다.
좋은 연습 방법
SVsQueryEditQuerySave 서비스를 사용하여 파일을 편집하기 전에 편집할 수 있는지 확인하고 저장하기 전에 저장할 수 있는지 확인합니다. 이렇게 하면 백업 및 업그레이드 구현이 소스 제어 하에 있는 프로젝트 파일, 권한이 부족한 파일 등을 처리하는 데 도움이 됩니다.
백업 및 업그레이드의 모든 단계에서 SVsUpgradeLogger 서비스를 사용하여 업그레이드 프로세스의 성공 또는 실패에 대한 정보를 제공합니다.
프로젝트 백업 및 업그레이드에 대한 자세한 내용은 vsshell2.idl의 IVsProjectUpgrade에 대한 주석을 참조하세요.
사용자 지정 프로젝트 업그레이드
제품의 다른 Visual Studio 버전 간에 프로젝트 파일에 있는 정보를 변경하는 경우 이전 버전에서 새 버전으로의 프로젝트 파일 업그레이드를 지원해야 합니다. Visual Studio 변환 마법사에 참여할 수 있는 업그레이드를 지원하려면 IVsProjectUpgradeViaFactory 인터페이스를 구현합니다. 이 인터페이스에는 복사 업그레이드에 사용할 수 있는 메커니즘만 포함되어 있습니다. 프로젝트 업그레이드는 솔루션의 일부가 열릴 때 수행됩니다. IVsProjectUpgradeViaFactory 인터페이스는 프로젝트 팩터리에서 구현되거나 적어도 프로젝트 팩터리에서 얻을 수 있어야 합니다.
IVsProjectUpgrade 인터페이스를 사용하는 이전 메커니즘은 계속 지원되지만 프로젝트의 일부가 열릴 때 프로젝트 시스템을 개념적으로 업그레이드합니다. 따라서 IVsProjectUpgrade 인터페이스는 IVsProjectUpgradeViaFactory 인터페이스가 호출 또는 구현되더라도 Visual Studio 환경에서 호출됩니다. 이 접근 방식을 사용하면 IVsProjectUpgradeViaFactory를 사용하여 업그레이드의 복사 및 프로젝트 전용 부분을 구현하고 나머지 작업은 IVsProjectUpgrade 인터페이스에서 바로(아마도 새 위치에서) 수행하도록 위임할 수 있습니다.
IVsProjectUpgrade의 샘플 구현은 VSSDK 샘플을 참조하세요.
프로젝트 업그레이드에서는 다음과 같은 시나리오가 발생합니다.
파일이 프로젝트에서 지원할 수 있는 형식보다 최신 형식인 경우 이를 설명하는 오류를 반환해야 합니다. 이 경우 제품의 이전 버전에 버전을 확인하는 코드가 포함되어 있다고 가정합니다.
UpgradeProject 메서드에 PUVFF_SXSBACKUP 플래그가 지정된 경우 업그레이드는 프로젝트를 열기 전에 현재 위치 업그레이드로 구현됩니다.
UpgradeProject 메서드에 PUVFF_COPYBACKUP 플래그가 지정된 경우 업그레이드는 복사 업그레이드로 구현됩니다.
UpgradeProject 호출에 UPF_SILENTMIGRATE 플래그가 지정된 경우 프로젝트가 열린 후 환경에서 사용자에게 프로젝트 파일을 현재 위치 업그레이드로 업그레이드하라는 메시지를 표시했습니다. 예를 들어 사용자가 이전 버전의 솔루션을 여는 경우 업그레이드하라는 메시지가 표시됩니다.
UpgradeProject 호출에 UPF_SILENTMIGRATE 플래그가 지정되지 않은 경우에는 사용자에게 프로젝트 파일을 업그레이드하라는 메시지를 표시해야 합니다.
다음은 업그레이드 프롬프트 메시지의 예입니다.
"'%1' 프로젝트는 이전 버전의 Visual Studio에서 만들었습니다. 이 버전의 Visual Studio에서 이 프로젝트를 열면 이전 버전의 Visual Studio에서 이 프로젝트를 열 수 없습니다. 이 프로젝트를 계속 여시겠습니까?”
IVsProjectUpgradeViaFactory를 구현하려면
프로젝트 팩터리 구현에서 IVsProjectUpgradeViaFactory 인터페이스의 메서드 특히, UpgradeProject 메서드를 구현하거나 프로젝트 팩터리 구현에서 해당 구현을 호출할 수 있게 합니다.
솔루션 열기의 일부로 현재 위치 업그레이드를 수행하려는 경우 UpgradeProject 구현에서 PUVFF_SXSBACKUP 플래그를
VSPUVF_FLAGS
매개 변수로 제공합니다.솔루션 열기의 일부로 현재 위치 업그레이드를 수행하려는 경우 UpgradeProject 구현에서 PUVFF_COPYBACKUP 플래그를
VSPUVF_FLAGS
매개 변수로 제공합니다.2단계와 3단계 모두의 경우 IVsQueryEditQuerySave2를 사용하는 실제 파일 업그레이드 단계는 아래의 “구현
IVsProjectUpgade
” 섹션에 설명된 대로 구현할 수도 있고 실제 파일 업그레이드를 IVsProjectUpgrade에 위임할 수도 있습니다.IVsUpgradeLogger의 메서드를 사용하여 Visual Studio 마이그레이션 마법사를 사용하는 사용자에게 업그레이드 관련 메시지를 게시합니다.
IVsFileUpgrade 인터페이스는 프로젝트 업그레이드의 일부로 수행해야 하는 모든 종류의 파일 업그레이드를 구현하는 데 사용됩니다. 이 인터페이스는 IVsProjectUpgradeViaFactory에서 호출되지는 않지만, 프로젝트 시스템의 일부이지만 기본 프로젝트 시스템에서 직접적으로 알지 못할 수도 있는 파일을 업그레이드하는 메커니즘을 제공됩니다. 예를 들어 나머지 프로젝트 시스템을 처리하는 개발 팀이 컴파일러 관련 파일 및 속성을 처리하지 않는 경우 이러한 상황이 발생할 수 있습니다.
IVsProjectUpgrade 구현
프로젝트 시스템에서 IVsProjectUpgrade만 구현하는 경우 Visual Studio 변환 마법사에 참여할 수 없습니다. 그러나 IVsProjectUpgradeViaFactory 인터페이스를 구현하더라도 여전히 파일 업그레이드를 IVsProjectUpgrade 구현에 위임할 수는 있습니다.
IVsProjectUpgrade를 구현하려면
사용자가 프로젝트를 열면 프로젝트가 열린 후 프로젝트에 대한 다른 사용자 작업을 수행할 수 있기 전에 환경에서 UpgradeProject 메서드가 호출됩니다. 사용자에게 솔루션을 업그레이드하라는 메시지가 이미 표시된 경우 UPF_SILENTMIGRATE 플래그가
grfUpgradeFlags
매개 변수에 전달됩니다. 사용자가 기존 프로젝트 추가 명령을 사용하는 등과 같이 프로젝트를 직접 여는 경우에는 UPF_SILENTMIGRATE 플래그가 전달되지 않으며 프로젝트에서 사용자에게 업그레이드하라는 메시지를 표시해야 합니다.UpgradeProject 호출에 응답하여 프로젝트에서는 프로젝트 파일이 업그레이드되었는지 평가해야 합니다. 프로젝트에서 프로젝트 형식을 새 버전으로 업그레이드할 필요가 없는 경우에는 간단히 S_OK 플래그를 반환할 수 있습니다.
프로젝트에서 프로젝트 형식을 새 버전으로 업그레이드해야 하는 경우에는 QueryEditFiles 메서드를 호출하고 tagVSQueryEditFlags 값을
rgfQueryEdit
매개 변수에 전달하여 프로젝트 파일을 수정할 수 있는지 여부를 확인해야 합니다. 그런 다음 프로젝트에서 다음을 수행해야 합니다.pfEditCanceled
매개 변수에서 반환된VSQueryEditResult
값이 QER_EditOK인 경우 프로젝트 파일을 쓸 수 있으므로 업그레이드를 진행할 수 있습니다.pfEditCanceled
매개 변수에서 반환된VSQueryEditResult
값이 QER_EditNotOK이고VSQueryEditResult
값에 QER_ReadOnlyNotUnderScc 비트가 설정된 경우에는 사용자가 권한 문제를 직접 해결해야 하므로 UpgradeProject에서 오류를 반환해야 합니다. 그런 다음 프로젝트에서 다음을 수행해야 합니다.ReportErrorInfo를 호출하여 사용자에게 오류를 보고하고 VS_E_PROJECTMIGRATIONFAILED 오류 코드를 IVsProjectUpgrade에 반환합니다.
VSQueryEditResult
값이 QER_EditNotOK이고VSQueryEditResultFlags
값에 QER_ReadOnlyUnderScc 비트가 설정된 경우에서 QueryEditFiles (QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits,...)를 호출하여 프로젝트 파일을 체크 아웃해야 합니다.
프로젝트 파일에 대한 QueryEditFiles 호출로 파일이 체크 아웃되고 최신 버전이 검색되는 경우에는 프로젝트가 언로드되었다가 다시 로드됩니다. 프로젝트의 다른 인스턴스가 생성되면 UpgradeProject 메서드가 다시 호출됩니다. 이 두 번째 호출에서 프로젝트 파일을 디스크에 쓸 수 있습니다. 프로젝트에서 프로젝트 파일의 복사본을 .OLD 확장명을 사용하는 이전 형식으로 저장하고 필요한 업그레이드 변경을 수행한 다음 프로젝트 파일을 새 형식으로 저장하는 것이 좋습니다. 마찬가지로 업그레이드 프로세스의 일부가 실패하면 메서드에서는 VS_E_PROJECTMIGRATIONFAILED를 반환하여 오류를 표시해야 합니다. 이로 인해 솔루션 탐색기에서 프로젝트가 언로드됩니다.
QueryEditFiles 메서드 호출(ReportOnly 값 지정)에서 QER_EditNotOK 및 QER_ReadOnlyUnderScc 플래그를 반환하는 경우에 대해 환경에서 수행되는 전체 프로세스를 이해해야 합니다.
사용자가 프로젝트 파일을 열려고 합니다.
환경에서 CanCreateProject 구현을 호출합니다.
CanCreateProject가
true
를 반환하는 경우 환경에서 CanCreateProject 구현을 호출합니다.환경에서 Load 구현을 호출하여 파일을 열고 프로젝트 개체(예: Project1)를 초기화합니다.
환경에서
IVsProjectUpgrade::UpgradeProject
구현을 호출하여 프로젝트 파일을 업그레이드해야 하는지 여부를 확인합니다.QueryEditFiles를 호출하고 QEF_ReportOnly 값을
rgfQueryEdit
매개 변수에 전달합니다.환경에서
VSQueryEditResult
에 대해 QER_EditNotOK를 반환하고VSQueryEditResultFlags
에 QER_ReadOnlyUnderScc 비트가 설정되 었습니다.IVsProjectUpgrade 구현에서
IVsQueryEditQuerySave::QueryEditFiles
(QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits)를 호출합니다.
이 호출로 인해 프로젝트 파일의 새 복사본이 체크 아웃되고 최신 버전이 검색될 수 있으며 프로젝트 파일을 다시 로드해야 합니다. 이때 다음 두 가지 중 하나가 발생합니다.
프로젝트 다시 로드를 직접 처리하는 경우 환경에서 ReloadItem (VSITEMID_ROOT) 구현을 호출합니다. 이 호출을 받는 경우 프로젝트의 첫 번째 인스턴스(Project1)를 다시 로드하고 계속 프로젝트 파일을 업그레이드합니다. GetProperty (VSHPROPID_HandlesOwnReload)에 대해
true
를 반환하는 경우 환경에서 사용자가 프로젝트 다시 로드를 직접 처리한다고 인식합니다.프로젝트 다시 로드를 직접 처리하지 않는 경우에는 GetProperty (VSHPROPID_HandlesOwnReload)에 대해
false
를 반환합니다. 이 경우 QueryEditFiles(QEF_ForceEdit_NoPrompting, QEF_DisallowInMemoryEdits)가 반환되기 전에 환경은 다음과 같이 프로젝트의 또 다른 새 인스턴스(예: Project2)를 만듭니다.환경에서 첫 번째 프로젝트 개체 Project1에 대해 Close를; 호출하여 이 개체를 비활성 상태로 둡니다.
환경에서
IVsProjectFactory::CreateProject
구현하여 프로젝트의 두 번째 인스턴스 Project2를 만듭니다.환경에서
IPersistFileFormat::Load
구현을 호출하여 파일을 열고 두 번째 프로젝트 개체 Project2를 초기화합니다.환경에서
IVsProjectUpgrade::UpgradeProject
를 두 번째로 호출하여 프로젝트 개체를 업그레이드해야 하는지 여부를 결정합니다. 그러나 이 호출은 프로젝트의 새로운 두 번째 인스턴스 Project2에 대해 수행됩니다. 이 프로젝트가 솔루션에 열려 있는 프로젝트입니다.참고 항목
첫 번째 프로젝트 Project1이 비활성 상태로 있는 인스턴스에서는 UpgradeProject 구현에 대한 첫 번째 호출에서 S_OK를 반환해야 합니다.
QueryEditFiles를 호출하고 QEF_ReportOnly 값을
rgfQueryEdit
매개 변수에 전달합니다.환경에서 QER_EditOK를 반환하고 프로젝트 파일을 쓸 수 있으므로 업그레이드를 진행할 수 있습니다.
업그레이드하지 않으면 IVsProjectUpgrade::UpgradeProject
에서 VS_E_PROJECTMIGRATIONFAILED를 반환합니다. 업그레이드가 필요하지 않거나 업그레이드하지 않으려면 IVsProjectUpgrade::UpgradeProject
호출을 no-op으로 처리합니다. VS_E_PROJECTMIGRATIONFAILED를 반환하는 경우 프로젝트에 대한 자리 표시자 노드가 솔루션에 추가됩니다.
프로젝트 항목 업그레이드
구현하지 않은 프로젝트 시스템 내에서 항목을 추가하거나 관리하는 경우 프로젝트 업그레이드 프로세스에 참여해야 할 수 있습니다. Crystal Reports는 프로젝트 시스템에 추가할 수 있는 항목의 예입니다.
일반적으로 프로젝트 항목 구현자는 이미 완전히 인스턴스화되고 업그레이드된 프로젝트를 활용하려고 합니다. 업그레이드 결정을 내리기 위해 프로젝트 참조가 무엇이고 다른 프로젝트 속성이 무엇인지 알아야 하기 때문입니다.
프로젝트 업그레이드 알림 받기
프로젝트 항목 구현에서 SolutionOrProjectUpgrading 플래그(vsshell80.idl에 정의됨)를 설정합니다. 이렇게 하면 Visual Studio 셸에서 프로젝트 시스템이 업그레이드 중이라고 판단할 때 프로젝트 항목 VSPackage가 자동으로 로드됩니다.
AdviseSolutionEvents 메서드를 통해 IVsSolutionEventsProjectUpgrade 인터페이스에 알립니다.
IVsSolutionEventsProjectUpgrade 인터페이스는 프로젝트 시스템 구현이 업그레이드 작업을 완료하고 업그레이드된 새 프로젝트가 생성된 후에 시작됩니다. 시나리오에 따라 IVsSolutionEventsProjectUpgrade 인터페이스는 OnAfterOpenSolution, OnAfterOpenProject 또는 OnAfterLoadProject 메서드 후에 실행됩니다.
프로젝트 항목 파일 업그레이드하기
프로젝트 항목 구현에서 파일 백업 프로세스를 신중하게 관리해야 합니다. 이는 특히 UpgradeProject 메서드의
fUpgradeFlag
매개 변수가 PUVFF_SXSBACKUP으로 설정되어 백업된 파일이 ".old"로 지정된 측면 파일을 따라 배치되는 병렬 백업에 특히 적용됩니다. 프로젝트를 업그레이드한 시스템 시간보다 오래된 백업 파일은 부실 파일로 지정할 수 있습니다. 또한 덮어쓰기를 방지하기 위해 특정 단계를 수행하지 않는 한 덮어쓸 수 있습니다.프로젝트 항목이 프로젝트 업그레이드 알림을 받을 때 Visual Studio 변환 마법사가 계속 표시됩니다. 따라서 IVsUpgradeLogger 인터페이스의 메서드를 사용하여 마법사 UI에 업그레이드 메시지를 제공해야 합니다.