데스크톱 애플리케이션 패키지 준비

이 문서에는 데스크톱 애플리케이션을 패키지하기 전에 알아야 할 사항이 나와 있습니다. 패키징 프로세스를 위해 애플리케이션을 준비하는 데 많은 작업을 수행할 필요가 없습니다. 하지만 아래 항목 중 하나라도 애플리케이션에 적용되는 경우 패키지하기 전에 이를 해결해야 합니다.

  • .NET 애플리케이션에는 4.6.2 이전 버전의 .NET Framework가 필요합니다. .NET 애플리케이션을 패키지하는 경우 애플리케이션에서 .NET Framework 4.6.2 이상을 대상으로 하는 것이 좋습니다. 패키지된 데스크톱 애플리케이션을 설치하고 실행하는 기능은 Windows 10, 버전 1607(1주년 업데이트라고도 함)에서 처음 도입되었으며, 이 OS 버전에는 기본적으로 .NET Framework 4.6.2가 포함되어 있습니다. 이후 OS 버전에는 이후 버전의 .NET Framework가 포함됩니다. 이후 버전의 Windows 10에 포함된 .NET의 전체 버전 목록은 이 문서를 참조하세요.

    패키지된 데스크톱 애플리케이션에서 4.6.2 이전 버전의 .NET Framework를 대상으로 하는 경우에는 대부분 작동합니다. 그러나 4.6.2 이전 버전을 대상으로 하는 경우 패키지된 데스크톱 애플리케이션을 사용자에게 배포하기 전에 완전히 테스트해야 합니다.

    • 4.0 - 4.6.1: 이러한 버전의 .NET Framework를 대상으로 하는 애플리케이션은 4.6.2 이상에서 문제없이 실행됩니다. 따라서 이러한 애플리케이션은 OS에 포함된 .NET Framework 버전을 사용하여 Windows 10 버전 1607 이상에서 변경 없이 설치하고 실행해야 합니다.

    • 2.0 및 3.5: 테스트에서 이러한 버전의 .NET Framework를 대상으로 하는 패키지된 데스크톱 애플리케이션은 일반적으로 작동하지만 일부 시나리오에서는 성능 문제가 발생할 수 있습니다. 이러한 패키지된 애플리케이션을 설치하고 실행하려면 .NET Framework 3.5 기능을 대상 머신에 설치해야 합니다(이 기능에는 .NET Framework 2.0 및 3.0도 포함되어 있음). 또한 이러한 애플리케이션을 패키지한 후에는 철저히 테스트해야 합니다.

  • 애플리케이션은 항상 관리자 보안 권한으로 실행됩니다. 대화형 사용자로 실행하는 동안 애플리케이션이 작동해야 합니다. 애플리케이션을 설치하는 사용자는 시스템 관리자가 아닐 수 있으므로 애플리케이션을 관리자 권한으로 실행해야 한다는 것은 표준 사용자의 경우 제대로 실행할 수 없음을 의미합니다. 앱을 Macirosoft Store에 게시하려는 경우 해당 기능의 일부에 대해 권한 상승이 필요한 앱은 스토어에 허용되지 않습니다.

  • 애플리케이션에는 커널 모드 드라이버 또는 Windows 서비스가 필요합니다. MSIX는 시스템 계정으로 실행해야 하는 커널 모드 드라이버 또는 Windows 서비스를 지원하지 않습니다. Windows 서비스 대신, 백그라운드 작업을 사용합니다.

  • 앱의 모듈은 in-process 방식으로 Windows 앱 패키지에 없는 프로세스에 로드됩니다. . 이것은 허용되지 않습니다. 즉 셸 확장과 같은 in-process 확장은 지원되지 않습니다. 그렇지만 두 앱이 같은 패키지에 있는 경우 두 앱의 프로세스 간 통신을 수행할 수 있습니다.

  • 애플리케이션에서 설치한 모든 확장이 애플리케이션을 설치한 위치에 설치되는지 확인합니다. Windows를 사용하는 경우 사용자와 IT 관리자는 패키지의 기본 설치 위치를 변경할 수 있습니다. "설정 -> 시스템 -> 스토리지 -> 더 많은 스토리지 설정 -> 새 콘텐츠가 저장되는 위치 변경 -> 새 앱 저장 위치"를 확인합니다. 애플리케이션을 통해 확장을 설치하는 경우 확장에 추가 설치 폴더 제한이 없어야 합니다. 예를 들어 일부 확장에서는 시스템 드라이브가 아닌 드라이브에 확장을 설치하지 못하도록 설정할 수 있습니다. 이로 인해 기본 위치가 변경되면 0x80073D01 (ERROR_DEPLOYMENT_BLOCKED_BY_POLICY) 오류가 발생합니다.

  • 애플리케이션은 사용자 지정 AUMID(애플리케이션 사용자 모델 ID)를 사용합니다. 프로세스에서 SetCurrentProcessExplicitAppUserModelID를 호출하여 자체 AUMID를 설정하는 경우 애플리케이션 모델 환경/Windows 앱 패키지에서 이에 대해 생성한 AUMID만 사용할 수 있습니다. 사용자 지정 AUMID를 정의할 수 없습니다.

  • 애플리케이션은 HKLM(HKEY_LOCAL_MACHINE) 레지스트리 하이브를 수정합니다. 애플리케이션에서 HKLM 키를 만들거나 수정하기 위해 이 키를 열려고 하면 액세스 거부 오류가 발생합니다. 애플리케이션에는 레지스트리에 대한 프라이빗 가상화 보기가 있으므로 사용자 및 머신 수준 레지스트리 하이브(HKLM 개념)가 적용되지 않습니다. 대신 HKEY_CURRENT_USER(HKCU)에 쓰는 것과 같은 HKLM 사용 목적을 달성할 수 있는 다른 방법을 찾아야 합니다.

  • 애플리케이션은 다른 앱을 시작하는 수단으로 ddeexec 레지스트리 하위 키를 사용합니다. 대신 앱 패키지 매니페스트의 다양 한 Activatable* 확장에 의해 구성된 DelegateExecute 동사 처리기 중 하나를 사용합니다.

  • 애플리케이션은 다른 앱과 데이터를 공유하기 위해 AppData 폴더 또는 레지스트리에 씁니다. 변환 후 AppData는 각 앱에 대한 프라이빗 저장소인 로컬 앱 데이터 저장소로 리디렉션됩니다.

    애플리케이션에서 HKEY_LOCAL_MACHINE 레지스트리 하이브에 쓰는 모든 항목은 격리된 이진 파일로 리디렉션되고, 애플리케이션에서 HKEY_CURRENT_USER 레지스트리 하이브에 쓰는 모든 항목은 사용자별, 앱별 프라이빗 위치에 배치됩니다. 파일 및 레지스트리 리디렉션에 대한 자세한 내용은 데스크톱 브리지의 백그라운드 작업을 참조하세요.

    프로세스 간에 데이터를 공유하는 다른 방법을 사용합니다. 자세한 내용은 설정 및 기타 앱 데이터 저장 및 검색을 참조하세요.

  • 애플리케이션에서 앱의 설치 디렉터리에 씁니다. 예를 들어 애플리케이션에서 exe와 동일한 디렉터리에 배치하는 로그 파일에 씁니다. 이것이 지원되지 않으면 로컬 앱 데이터 저장소 등의 다른 위치를 찾아야 합니다.

  • 애플리케이션에서 현재 작업 디렉터리를 사용합니다. 런타임에서 패키지된 데스크톱 애플리케이션은 이전에 데스크톱 .LNK 바로 가기에서 지정한 것과 동일한 작업 디렉터리를 가져올 수 없습니다. 애플리케이션이 제대로 작동하기 위해 올바른 디렉터리를 사용해야 하는 경우 런타임에 CWD를 변경해야 합니다.

    참고

    앱에서 설치 디렉터리에 쓰거나 현재 작업 디렉터리를 사용해야 하는 경우 패키지 지원 프레임워크를 사용하여 런타임 픽스업을 패키지에 추가하는 것을 고려할 수도 있습니다. 자세한 내용은 이 문서를 참조하세요.

  • 애플리케이션 설치에는 사용자 상호 작용이 필요합니다. 애플리케이션 설치 관리자는 자동으로 실행될 수 있어야 하며, 설치되지 않은 모든 필수 구성 요소를 기본적으로 깨끗한 OS 이미지에 설치해야 합니다.

  • 애플리케이션에는 UIAccess가 필요합니다. 애플리케이션에서 UAC 매니페스트의 requestedExecutionLevel 요소에 UIAccess=true를 지정하는 경우 현재 MSIX로 변환할 수 없습니다. 자세한 내용은 UI 자동화 보안 개요를 참조하세요.

  • 애플리케이션에서 COM 개체를 공개합니다. 패키지 내의 프로세스와 확장은 in-process 및 OOP(out-of-process) 방식 모두에서 COM 및 OLE 서버를 등록하고 사용할 수 있습니다. 크리에이터스 업데이트에는 이제 패키지 외부에서 볼 수 있는 OOP COM 및 OLE 서버를 등록하는 기능을 제공하는 패키지된 COM 지원이 추가되었습니다. 데스크톱 브리지에 대한 COM 서버 및 OLE 문서 지원을 참조하세요.

    패키지된 COM 지원은 기존 COM API에서 작동하지만, 패키지된 COM의 위치가 프라이빗 위치에 있으므로 레지스트리를 직접 읽는 애플리케이션 확장에는 작동하지 않습니다.

  • 다른 프로세스에서 사용할 수 있도록 애플리케이션에서 GAC 어셈블리를 공개합니다. Windows 앱 패키지 외부의 실행 파일에서 시작된 프로세스에서 사용할 GAC 어셈블리는 애플리케이션에서 공개할 수 없습니다. 패키지 내의 프로세스는 GAC 어셈블리를 정상적으로 등록하고 사용할 수 있지만 외부에서 볼 수는 없습니다. 즉, OLE와 같은 interop 시나리오는 외부 프로세스에서 호출되는 경우 작동하지 않습니다.

  • 애플리케이션에서 CRT(C 런타임 라이브러리)를 지원하지 않는 방식으로 연결하고 있습니다. Microsoft C/C++ 런타임 라이브러리는 Microsoft Windows 운영 체제용 프로그래밍 루틴을 제공합니다. 이러한 루틴은 C 및 C++ 언어에서 제공하지 않는 많은 일반적인 프로그래밍 작업을 자동화합니다. 애플리케이션에서 C/C++ 런타임 라이브러리를 사용하는 경우 해당 라이브러리가 지원되는 방식으로 연결되어 있는지 확인해야 합니다.

    Visual Studio 2017에서는 현재 버전의 CRT 코드에 대한 정적 및 동적 연결(코드에서 공용 DLL 파일을 사용할 수 있도록 함) 또는 정적 연결(라이브러리를 코드에 직접 연결함)을 모두 지원합니다. 가능한 경우 애플리케이션에서 VS 2017과의 동적 연결을 사용하는 것이 좋습니다.

    이전 버전의 Visual Studio에서의 지원은 각기 다릅니다. 자세한 내용은 다음 표를 참조하세요.

    Visual Studio 버전동적 연결정적 연결
    2005(VC 8)지원되지 않음지원 여부
    2008(VC 9)지원되지 않음지원 여부
    2010(VC 10)지원 여부지원 여부
    2012(VC 11)지원 여부지원되지 않음
    2013(VC 12)지원 여부지원되지 않음
    2015 및 2017(VC 14)지원 여부지원 여부

    참고: 모든 경우에서 공개적으로 사용 가능한 최신 CRT에 연결해야 합니다.

  • 애플리케이션에서 Windows 병렬 폴더에서 어셈블리를 설치하고 로드합니다. 예를 들어 애플리케이션에서 C 런타임 라이브러리 VC8 또는 VC9를 사용하고 Windows 병렬 폴더에서 이러한 라이브러리를 동적으로 연결합니다. 즉, 코드에서 공유 폴더의 공용 DLL 파일을 사용합니다. 이는 지원되지 않습니다. 재배포 가능 라이브러리 파일을 코드에 직접 연결하여 정적으로 연결해야 합니다.

  • 애플리케이션에서 System32/SysWOW64 폴더의 종속성을 사용합니다. 이러한 DLL이 작동하도록 하려면 해당 DLL을 Windows 앱 패키지의 가상 파일 시스템 부분에 포함시켜야 합니다. 이렇게 하면 DLL이 System32/SysWOW64 폴더에 설치된 것처럼 애플리케이션이 작동합니다. 패키지의 루트에 VFS 라는 폴더를 만듭니다. 해당 폴더 안에 SystemX64SystemX86 폴더를 만듭니다. 그런 다음 32비트 버전의 DLL은 SystemX86 폴더에 넣고 64비트 버전은 SystemX64 폴더에 넣습니다.

  • 앱에서 VCLibs 프레임워크 패키지를 사용합니다. C++ Win32 앱을 변환하는 경우 Visual C++ 런타임 배포를 처리해야 합니다. Visual Studio 2019 및 Windows SDK에는 Visual C++ 런타임 버전 11.0, 12.0 및 14.0용 최신 프레임워크 패키지가 다음 폴더에 포함되어 있습니다.

    • VC 14.0 프레임워크 패키지: C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop\14.0

    • VC 12.0 프레임워크 패키지: C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop.120\14.0

    • VC 11.0 프레임워크 패키지: C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop.110\14.0

    이러한 패키지 중 하나를 사용하려면 패키지 매니페스트에서 해당 패키지를 종속성으로 참조해야 합니다. 고객이 Microsoft Store에서 앱의 일반 정품 버전을 설치하면 스토어에서 앱과 함께 패키지가 설치됩니다. 앱을 사이드로드하는 경우 종속성이 설치되지 않습니다. 종속성을 수동으로 설치하려면 위에 나열된 설치 폴더에 있는 x86, x64 또는 ARM에 적절한 .appx 패키지를 사용하여 적절한 프레임워크 패키지를 설치해야 합니다.

    앱에서 Visual C++ 런타임 프레임워크 패키지를 참조하려면 다음을 수행합니다.

    1. 앱에서 사용하는 Visual C++ 런타임 버전에 대해 위에 나열된 프레임워크 패키지 설치 폴더로 이동합니다.

    2. 해당 폴더에서 SDKManifest.xml 파일을 열고, 런타임의 디버그 또는 일반 정품 버전을 사용하는지 여부에 따라 FrameworkIdentity-Debug 또는 FrameworkIdentity-Retail 특성을 찾고, 해당 특성에서 NameMinVersion 값을 복사합니다. 예를 들어 현재 VC 14.0 프레임워크 패키지에 대한 FrameworkIdentity-Retail 특성은 다음과 같습니다.

      FrameworkIdentity-Retail = "Name = Microsoft.VCLibs.140.00.UWPDesktop, MinVersion = 14.0.27323.0, Publisher = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'"
      
    3. 앱의 패키지 매니페스트에서 다음 <PackageDependency> 요소를 <Dependencies> 노드 아래에 추가합니다. NameMinVersion 값을 이전 단계에서 복사한 값으로 바꿔야 합니다. 다음 예제에서는 VC 14.0 프레임워크 패키지의 현재 버전에 대한 종속성을 지정합니다.

      <PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.27323.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
      
  • 사용자 지정 점프 목록이 애플리케이션에 포함됩니다. 점프 목록을 사용할 때 알아야 할 몇 가지 문제와 주의 사항이 있습니다.

    • 앱의 아키텍처가 OS와 일치하지 않습니다. 애플리케이션과 OS 아키텍처가 일치하지 않으면(예: x64 Windows에서 실행되는 x86 애플리케이션) 현재 점프 목록이 제대로 작동하지 않습니다. 지금은 애플리케이션을 일치하는 아키텍처로 다시 컴파일하는 것 외에는 다른 해결 방법이 없습니다.

    • 애플리케이션에서 점프 목록 항목을 만들고, ICustomDestinationList::SetAppID 또는 SetCurrentProcessExplicitAppUserModelID를 호출합니다. 코드에 프로그래밍 방식으로 AppID를 설정하지 마세요. 그러면 점프 목록 항목이 나타나지 않게 됩니다. 애플리케이션에 사용자 지정 ID가 필요한 경우 매니페스트 파일을 사용하여 지정합니다. 지침은 수동으로 데스크톱 애플리케이션 패키징을 참조하세요. 응용 프로그램의 AppID는 YOUR_PRAID_HERE 섹션에 지정됩니다.

    • 애플리케이션에서 패키지의 실행 파일을 참조하는 점프 목록 셸 링크를 추가합니다. 점프 목록에서 바로 패키지의 실행 파일을 시작할 수는 없습니다(앱 자체의 .exe에 대한 절대 경로는 예외). 대신, 앱 실행 별칭(패키지된 데스크톱 애플리케이션에서 PATH에 있는 것처럼 키워드를 통해 시작할 수 있도록 함)을 등록하고, 링크 대상 경로를 별칭으로 대신 설정합니다. appExecutionAlias 확장을 사용하는 방법에 대한 자세한 내용은 데스크톱 애플리케이션을 Windows 10과 통합을 참조하세요. 점프 목록에 원래 .exe와 일치하는 링크의 자산이 필요할 경우 SetIconLocation을 사용하여 아이콘과 같은 자산을 설정하고 다른 사용자 지정 항목에 사용하는 것 같은 PKEY_Title로 표시 이름을 설정해야 합니다.

    • 애플리케이션에서 앱 패키지의 자산을 절대 경로를 통해 참조하는 점프 목록 항목을 추가합니다. 패키지가 업데이트되면 애플리케이션의 설치 경로가 변경되어 자산의 위치(예: 아이콘, 문서, 실행 파일 등)가 변경될 수 있습니다. 점프 목록 항목이 절대 경로를 통해 이러한 자산을 참조하는 경우 경로가 올바르게 확인되도록 애플리케이션에서 점프 목록을 주기적으로(예: 애플리케이션 시작 시) 새로 고쳐야 합니다. 또는 package-relative ms-resource URI 스키마(언어, DPI 및 고대비 인식 가능)를 사용하여 문자열 및 이미지 자산을 참조할 수 있는 UWP Windows.UI.StartScreen.JumpList API를 사용하세요.

  • 애플리케이션에서 작업을 수행하기 위한 유틸리티를 시작합니다. PowerShell 및 Cmd.exe와 같은 명령 유틸리티를 시작하지 않도록 방지합니다. 실제로 사용자가 Windows 10 S를 실행하는 시스템에 애플리케이션을 설치하는 경우 애플리케이션에서 이러한 유틸리티를 전혀 시작할 수 없습니다. 그러면 Microsoft Store에 제출된 모든 앱이 Windows 10 S와 호환되어야 하므로 애플리케이션이 Microsoft Store에 제출되지 않을 수 있습니다.

    유틸리티를 시작하면 운영 체제에서 정보를 가져오거나, 레지스트리에 액세스하거나, 시스템 기능에 액세스하는 편리한 방법을 제공할 수 있는 경우가 많습니다. 그러나 UWP API를 사용하여 이러한 종류의 작업을 대신 수행할 수 있습니다. 이러한 API는 별도의 실행 파일이 필요하지 않으므로 성능이 뛰어나지만, 더 중요한 것은 애플리케이션에서 패키지 외부에 도달하지 못하도록 방지하는 것입니다. 앱의 디자인은 패키지한 애플리케이션에 제공되는 격리, 신뢰 및 보안과 일관성 있게 유지되지만, 애플리케이션은 Windows 10 S를 실행하는 시스템에서 예상대로 작동합니다.

  • 애플리케이션에서 추가 기능, 플러그 인 또는 확장을 호스팅합니다. 대부분의 경우 확장이 패키지되지 않으면 COM 스타일 확장이 계속 작동하고 완전 신뢰로 설치됩니다. 왜냐하면 이러한 설치 관리자에서 완전 신뢰 기능을 사용하여 레지스트리를 수정하고, 호스트 애플리케이션에서 해당 레지스트리를 찾을 것이라고 예상하는 위치라면 어디에나 확장 파일을 배치할 수 있기 때문입니다.

    그러나 이러한 확장을 패키지한 다음, Windows 앱 패키지로서 설치되면 각 패키지(호스트 애플리케이션 및 확장)가 다른 패키지와 격리되므로 해당 확장이 작동하지 않습니다. 애플리케이션이 시스템에서 격리되는 방법에 대한 자세한 내용은 데스크톱 브리지의 백그라운드 작업을 참조하세요.

    사용자가 Windows 10 S를 실행하는 시스템에 설치하는 모든 애플리케이션과 확장은 Windows 앱 패키지로 설치해야 합니다. 따라서 확장을 패키지하거나 기여자가 패키지하도록 하려면 호스트 애플리케이션 패키지와 확장 패키지 간의 통신을 원활하게 수행할 수 있는 방법을 고려합니다. 이를 수행할 수 있는 한 가지 방법은 앱 서비스를 사용하는 것입니다.

  • 애플리케이션에서 코드를 생성합니다. 애플리케이션은 메모리에서 사용하는 코드를 생성할 수 있지만, Windows 앱 인증 프로세스에서 앱을 제출하기 전에 생성된 코드의 유효성을 검사할 수 없으므로 해당 코드를 디스크에 쓰지 않도록 방지해야 합니다. 또한 코드를 디스크에 쓰는 앱은 Windows 10 S를 실행하는 시스템에서 제대로 실행되지 않습니다. 이렇게 하면 Microsoft Store에 제출된 모든 앱이 Windows 10 S와 호환되어야 하므로 애플리케이션이 Microsoft Store에 제출되지 않도록 차단할 수 있습니다.

중요

Windows 앱 패키지가 만들어지면 Windows 10 S를 실행하는 시스템에서 애플리케이션이 제대로 작동하는지 테스트하세요. Microsoft Store에 제출된 모든 앱은 Windows 10 S와 호환되어야 합니다. 호환되지 않는 앱은 스토어에서 허용되지 않습니다. Windows 10 S용 Windows 앱 테스트를 참조하세요.