Windows에서 패키지된 데스크톱 앱을 실행하는 방법 이해

이 문서에서는 데스크톱 애플리케이션용 Windows 앱 패키지를 만들 때 파일 및 레지스트리 항목에 어떤 일이 발생하는지 자세히 살펴봅니다.

최신 패키지의 주요 목표는 다른 앱과의 호환성을 최대한 유지하면서 애플리케이션 상태를 시스템 상태에서 분리하는 것입니다. Windows 10은 MSIX 패키지 내부에 애플리케이션을 배치한 다음, 런타임에 파일 시스템과 레지스트리의 변경 내용을 탐지하여 리디렉션하는 방식으로 이 목표를 달성합니다.

데스크톱 애플리케이션용으로 만든 패키지는 데스크톱 전용의 완전 신뢰 애플리케이션이며, 가상화되거나 샌드박스가 적용되지 않습니다. 이렇게 하면 기존의 데스크톱 애플리케이션이 수행한 방식과 동일하게 다른 앱을 조작할 수 있습니다.

설치

앱 패키지는 C:\Program Files\WindowsApps\package_name 아래 app_name.exe 실행 파일을 사용하여 설치됩니다. 각 패키지 폴더에는 패키지 앱에 대한 특수 XML 네임스페이스를 포함하는 매니페스트(AppxManifest.xml)가 들어 있습니다. 해당 매니페스트 파일 내에는 완전 신뢰 앱을 참조하는 <EntryPoint> 요소가 있습니다. 애플리케이션이 시작되면 애플리케이션은 앱 컨테이너 내에서 실행되지 않고, 대신 평소와 같이 해당 사용자 권한으로 실행됩니다.

배포 후에 패키지 파일은 운영 체제에 의해 읽기 전용으로 표시되고 잠깁니다. 이 파일이 변조되면 Windows에서 앱 시작을 차단합니다.

파일 시스템

OS는 폴더 위치에 따라 패키지된 데스크톱 애플리케이션에 대해 서로 다른 수준의 파일 시스템 작업을 지원합니다.

디바이스에 최적화

디스크 스토리지 공간에 최적화하기 위해 파일 중복을 방지하고 파일을 다운로드할 때 필요한 대역폭을 줄이기 위해 OS는 단일 스토리지와 파일 하드 링크를 활용합니다. 사용자가 MSIX 패키지를 다운로드할 때 AppxManifest.xml은 패키지에 포함된 데이터가 이전에 설치된 패키지가 디스크에 있는지 확인하는 데 사용됩니다. 여러 MSIX 패키지에 동일한 파일이 있는 경우 OS는 공유 파일을 디스크에 한 번만 저장하고 두 패키지에서 공유 파일로 하드 링크를 만듭니다. 파일은 64k개 블록으로 다운로드되므로 다운로드 중인 파일의 일부가 디스크에 존재하더라도 다른 증분만 다운로드됩니다. 이렇게 하면 다운로드에 사용되는 대역폭이 줄어듭니다.

Windows 10 버전 1903 이상의 AppData 작업

사용자의 AppData 폴더(예: C:\Users\user_name\AppData)에 새로 생성된 모든 파일 및 폴더는 사용자별, 앱별 프라이빗 위치에 기록되지만 런타임에 병합되어 실제 AppData 위치에 표시됩니다. 따라서 애플리케이션 자체에서만 사용되는 아티팩트의 상태를 어느 정도 분리할 수 있으며, 애플리케이션이 제거될 때 시스템에서 해당 파일을 정리할 수 있습니다. 애플리케이션과 OS 간의 높은 호환성 및 상호 작용을 제공하기 위해 사용자의 AppData 폴더에 있는 기존 파일을 수정하는 것이 허용됩니다. 이렇게 하면 애플리케이션에서 수정한 파일 또는 디렉터리 변경 내용을 OS가 알게 되므로 파일 시스템 "문제"가 줄어듭니다. 또한 상태 분리를 통해 패키지 데스크톱 애플리케이션은 동일한 애플리케이션의 비-패키지 버전이 중단된 위치를 선택할 수 있습니다. OS는 사용자의 AppData 폴더에 VFS(가상 파일 시스템) 폴더를 지원하지 않습니다.

Windows 10 버전 1809 이하의 AppData 작업

만들기, 삭제 및 업데이트를 포함하여 사용자의 AppData 폴더(예: C:\Users\user_name\AppData)에 대한 모든 쓰기는 사용자별, 앱별 프라이빗 위치에 기록 중 복사됩니다. 이 때문에 패키지 애플리케이션에서 실제로 프라이빗 복사본을 수정하는 경우 실제 AppData를 편집하고 있다고 착각할 수 있습니다. 시스템은 이렇게 쓰기를 리디렉션하여 앱에서 수행된 모든 파일 수정 내용을 추적할 수 있습니다. 따라서 애플리케이션을 제거할 때 시스템에서 해당 파일을 제거하여 시스템 "문제"를 줄이고 사용자에게 보다 나은 앱 제거 환경을 제공할 수 있습니다.

기타 폴더

AppData 리디렉션 외에도, Windows의 잘 알려진 폴더(System32, Program Files (x86) 등)는 앱 패키지의 해당 디렉터리와 동적으로 병합됩니다. 각 패키지의 루트에는 "VFS"라는 폴더가 포함되어 있습니다. VFS 디렉터리에 있는 파일이나 디렉터리의 읽기 권한은 런타임 시 각각 해당하는 네이티브 권한으로 병합됩니다. 예를 들어 애플리케이션에 C:\Program Files\WindowsApps\package_name\VFS\SystemX86\vc10.dll 이 앱 패키지의 일부로 포함될 수 있지만, 파일은 C:\Windows\System32\vc10.dll 에 설치되는 것으로 나타납니다. 이렇게 하면 패키지가 없는 위치에서도 파일이 있을 수 있다고 예상하는 데스크톱 애플리케이션과 호환성을 유지합니다.

앱 패키지에서 파일/폴더에 대한 쓰기는 허용되지 않습니다. 패키지에 포함되지 않은 파일과 폴더에 대한 쓰기는 OS에서 무시되며, 사용자에게 권한이 있어야만 허용됩니다.

일반 작업

다음 간단한 참조 표에서는 일반적인 파일 시스템 작업과 OS에서 이러한 작업을 처리하는 방법을 보여줍니다.

작업 결과 예제
잘 알려진 Windows 파일이나 폴더를 읽거나 열거 해당하는 로컬 시스템 항목과 C:\Program Files\package_name\VFS\well_known_folder 의 동적 병합입니다. C:\Windows\System32 를 읽으면 C:\Windows\System32 콘텐츠와 C:\Program Files\WindowsApps\package_name\VFS\SystemX86 콘텐츠가 반환됩니다.
AppData에서 쓰기 Windows 10, 버전 1903 이상: 다음 디렉터리에 만들어진 새 파일 및 폴더는 사용자별, 패키지별 프라이빗 위치로 리디렉션됩니다.
  • 로컬
  • Local\Microsoft
  • 로밍
  • Roaming\Microsoft
  • Roaming\Microsoft\Windows\Start Menu\Programs
파일 열기 명령에 대한 응답으로, OS는 먼저 사용자별, 패키지별 위치에서 파일을 엽니다. 이 위치가 없으면 OS는 실제 AppData 위치에서 파일을 열려고 시도합니다. 실제 AppData 위치에서 파일이 열리면 해당 파일에 대한 가상화가 발생하지 않습니다. 사용자에게 권한이 있는 경우 AppData 아래의 파일을 삭제할 수 있습니다.

Windows 10, 버전 1809 이하: 사용자별, 앱별 위치에 기록 중 복사됩니다.

일반적으로 AppData는 C:\Users\user_name\AppData 입니다.
패키지 내 기록 허용되지 않습니다. 패키지가 읽기 전용인 경우 C:\Program Files\WindowsApps\package_name 내 기록은 허용되지 않습니다.
패키지 외부에 기록 사용자에게 권한이 있으면 허용됩니다. C:\Windows\System32\foo.dll 에 대한 기록은 패키지에 C:\Program Files\WindowsApps\package_name\VFS\SystemX86\foo.dll 이 없고 사용자에게 권한이 있으면 허용됩니다.

패키지에 포함된 VFS 위치

다음 표에서 패키지의 일부로 제공된 파일이 앱에 대한 시스템에 오버레이된 위치를 보여 줍니다. 파일이 실제로 C:\Program Files\WindowsApps\package_name\VFS 내 리디렉션된 위치에 있을 경우 애플리케이션은 이러한 파일이 나열된 시스템 위치에 있다고 인식합니다. FOLDERID 위치는 KNOWNFOLDERID 상수입니다.

시스템 위치 리디렉션된 위치([PackageRoot]\VFS) 아키텍처에서 유효
FOLDERID_SystemX86 SystemX86 x86, amd64
FOLDERID_System SystemX64 amd64
FOLDERID_ProgramFilesX86 ProgramFilesX86 x86, amd6
FOLDERID_ProgramFilesX64 ProgramFilesX64 amd64
FOLDERID_ProgramFilesCommonX86 ProgramFilesCommonX86 x86, amd64
FOLDERID_ProgramFilesCommonX64 ProgramFilesCommonX64 amd64
FOLDERID_Windows Windows x86, amd64
FOLDERID_ProgramData Common AppData x86, amd64
FOLDERID_System\catroot AppVSystem32Catroot x86, amd64
FOLDERID_System\catroot2 AppVSystem32Catroot2 x86, amd64
FOLDERID_System\drivers\etc AppVSystem32DriversEtc x86, amd64
FOLDERID_System\driverstore AppVSystem32Driverstore x86, amd64
FOLDERID_System\logfiles AppVSystem32Logfiles x86, amd64
FOLDERID_System\spool AppVSystem32Spool x86, amd64

레지스트리

앱 패키지에는 registry.dat 파일이 포함되어 있어 실제 레지스트리의 HKLM\Software 와 논리적으로 같은 역할을 합니다. 런타임에 해당 가상 레지스트리는 이 하이브의 콘텐츠를 네이티브 시스템 하이브에 병합하여 두 하이브의 단일 뷰를 제공합니다. 예를 들어, registry.dat에 단일 키 "Foo"가 포함되어 있으면 런타임에 HKLM\Software 를 읽으면 모든 네이티브 시스템 키뿐 아니라 “Foo”도 포함되어 표시됩니다.

MSIX 패키지에는 HKLM 및 HKCU 키가 포함되어 있지만 다르게 처리됩니다. HKLM\Software 의 키만 패키지에 포함됩니다. HKCU 또는 레지스트리의 다른 부분에 있는 키는 포함되지 않습니다. 패키지에서 키 또는 값에 대한 기록은 허용되지 않습니다. 패키지에 포함되지 않은 키 또는 값에 대한 쓰기는 사용자에게 권한이 있어야만 허용됩니다.

HKCU에서 모든 쓰기는 프라이빗 사용자별/앱별 위치에 기록 중 복사됩니다. 일반적으로 설치 제거 프로그램에서는 HKEY_CURRENT_USER 를 정리할 수 없습니다. 로그아웃된 사용자의 레지스트리 데이터는 마운트되지 않고 사용할 수 없습니다.

모든 쓰기는 패키지 업그레이드 중에 유지되며 애플리케이션을 완전히 제거해야만 삭제됩니다.

일반 작업

다음 간단한 참조 표에서는 일반적인 레지스트리 작업과 OS에서 이러한 작업을 처리하는 방법을 보여줍니다.

작업 결과 예제
HKLM\Software 를 읽거나 열거 로컬 시스템에 해당하는 하이브와 패키지 하이브를 동적으로 병합합니다. registry.dat에 단일 키 "Foo"가 포함되어 있으면 런타임에 HKLM\Software 에서는 HKLM\SoftwareHKLM\Software\Foo 의 두 콘텐츠가 모두 표시됩니다.
HKCU에서 쓰기 사용자별/앱별 프라이빗 위치에 기록 중 복사됩니다. 파일용 AppData와 동일합니다.
패키지 내에 씁니다. 허용되지 않습니다. 패키지가 읽기 전용인 경우 HKLM\Software 내 쓰기의 경우 패키지 하이브에 해당 키/값이 있는 경우 허용되지 않습니다.
패키지 외부에 기록 OS에서 무시됩니다. 사용자에게 권한이 있으면 허용됩니다. HKLM\Software 내 쓰기의 경우 패키지 하이브에 해당 키/값이 없고 사용자에게 정확한 액세스 권한이 있는 한 허용됩니다.

제거

사용자가 패키지를 제거하면 C:\Program Files\WindowsApps\package_name 에 있는 모든 파일 및 폴더가 제거되고, 패키징 프로세스 중에 캡처되어 AppData 또는 레지스트리로 리디렉션된 쓰기도 제거됩니다.