다음을 통해 공유


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

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

  • .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도 포함됨). 또한 이러한 애플리케이션을 패키지한 후 철저히 테스트해야 합니다.

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

  • 애플리케이션에는 Windows 드라이버가 필요합니다. MSIX는 Windows 드라이버를 지원하지 않습니다.

  • 애플리케이션에는 사용자 Windows 서비스가 필요합니다. MSIX는 사용자별 Windows 서비스를 지원하지 않습니다. MSIX는 정의된 시스템 계정(LocalSystem, LocalService 또는 NetworkService) 중 하나에서 실행되는 세션 0(컴퓨터당) 서비스를 지원합니다. 사용자 Windows 서비스 대신 백그라운드 작업을 사용합니다.

  • 귀하의 앱 모듈은 Windows 앱 패키지가 아닌 프로세스 내부에서 로드됩니다. 이는 허용되지 않습니다. 즉, 셸 확장과 같은 In-Process 확장은 지원되지 않습니다. 그러나 동일한 패키지에 두 개의 앱이 있는 경우 두 앱 간에 프로세스 간 통신을 수행할 수 있습니다.

  • 애플리케이션에서 설치한 모든 확장이 애플리케이션이 설치된 위치에 설치되는지 확인합니다. Windows를 사용하면 사용자와 IT 관리자가 패키지의 기본 설치 위치를 변경할 수 있습니다. 다음 "설정->시스템->저장소->추가 저장소 설정-> 새 콘텐츠가 저장될 위치 변경-> 새 앱이 저장될 위치"를 참조하세요. 애플리케이션을 사용하여 확장을 설치하는 경우 확장에 추가 설치 폴더 제한이 없는지 확인합니다. 예를 들어 일부 확장은 비 시스템 드라이브에 확장을 설치하지 않도록 설정할 수 있습니다. 이렇게 하면 기본 위치가 변경된 경우 오류 0x80073D01(ERROR_DEPLOYMENT_BLOCKED_BY_POLICY)가 발생합니다.

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

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

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

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

    애플리케이션이 HKEY_LOCAL_MACHINE 레지스트리 하이브에 쓰는 모든 항목은 격리된 이진 파일로 리디렉션되고 애플리케이션이 HKEY_CURRENT_USER 레지스트리 하이브에 쓰는 모든 항목은 사용자별 개인 앱별 위치에 배치됩니다. 파일 및 레지스트리 리디렉션에 대한 자세한 내용은 데스크톱 브리지의 비하인드 스토리를 참조하세요.

    프로세스 간 데이터 공유를 위한 다른 수단을 사용하십시오. 자세한 내용은 스토어를 참조하고 설정 및 기타 앱 데이터검색합니다.

  • 귀하의 애플리케이션이 앱의 설치 디렉터리에 데이터를 기록합니다. 예를 들어, 애플리케이션이 exe와 동일한 디렉터리에 있는 로그 파일에 데이터를 기록합니다. 지원되지 않으므로 로컬 앱 데이터 저장소와 같은 다른 위치를 찾아야 합니다.

  • 애플리케이션은 현재 작업 디렉터리를 사용합니다. 런타임 시 패키지된 데스크톱 애플리케이션은 데스크톱 .LNK 바로 가기에서 이전에 지정한 것과 동일한 작업 디렉터리를 얻지 못합니다. 애플리케이션이 올바르게 작동하려면 올바른 디렉터리가 있어야 하는 경우 런타임에 CWD를 변경해야 합니다.

    비고

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

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

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

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

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

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

    Visual Studio 2017은 코드에서 일반적인 DLL 파일 또는 정적 연결을 사용하여 라이브러리를 코드에 직접 연결하여 CRT의 현재 버전에 연결할 수 있도록 정적 및 동적 연결을 모두 지원합니다. 가능하면 애플리케이션에서 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이 작동하려면 Windows 앱 패키지의 가상 파일 시스템 부분에 DLL을 포함해야 합니다. 이렇게 하면 DLL이 System32/SysWOW64 폴더에 설치된 것처럼 애플리케이션이 동작합니다. 패키지의 루트에서 VFS라는 폴더를 만듭니다. 해당 폴더 내에 SystemX64SystemX86 폴더를 만듭니다. 그런 다음, 32비트 버전의 DLL을 SystemX86 폴더에 배치하고 SystemX64 폴더에 64 비트 버전을 배치합니다.

  • 앱은 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을 가진 표시 이름을 설정해야 합니다.

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

  • 애플리케이션이 작업을 수행하는 유틸리티를 시작합니다. 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 앱 테스트를 참조하세요.