Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 2개 있습니다.)

Windows 10 - ClickOnce 배포처럼 사용할 수 있는 MSIX 설치 파일

Windows 응용 프로그램 방식 중 Store App을 한 번이라도 만들어 Store에 올려 본 분이라면 msix 배포를 어떤 식으로든 사용해 봤을 것입니다. 한때는, msix가 Store 응용 프로그램을 위한 설치 파일이었는데 다르게 사용하면 기존의 ClickOnce처럼 응용 프로그램을 배포하는 것도 가능합니다. 이에 대해 직접 실습을 해보면서 ^^ 알아볼까요?




우선, msix로 설치할 예제 응용 프로그램이 필요한데요, Visual Studio에서 단순하게 (최소 .NET Framework 4.6.1 이상의 버전을 대상으로 하는) Console/WinForm/WPF 프로젝트를 하나 생성합니다. (이 글에서는 간단하게 Console 프로젝트로 하겠습니다.)

using System.Windows.Forms;

MessageBox.Show("TEST");

자, 그럼 이렇게 만든 프로젝트를 패키징 해야겠지요. 이를 위해 새 프로젝트 창에서 "Windows Application Package Project"를 추가합니다. 그럼 다음과 같이 배포 대상의 Windows 10 버전을 선택하는 화면이 뜨는데요,

msix_pacakge_1.png

그렇습니다, MSIX 패키지는 기본적으로 Microsoft Store에 등록할 설치 파일이므로 최소 Windows 10을 대상으로만 배포할 응용 프로그램에 한해 설치 파일로써 의미가 있습니다. 이후 진행하면 Package.appxmanifest 파일을 포함한 프로젝트를 볼 수 있습니다.

msix_pacakge_2.png

(Package.appxmanifest 파일의 세부 내용은 원하는 데로 설정할 수 있지만 인증서만큼은 반드시 지정해야 합니다.)

가장 중요한 것은 패키지 프로젝트가 배포할 응용 프로그램이 어떤 것인지를 지정하는 것인데요, 이것은 다음 화면과 같이 "Applications" 노드를 우클릭해 "Add Referencees..." 메뉴를 선택해 나타나는 "Reference Manager" 창을 통해 선택할 수 있습니다.

msix_pacakge_3.png

사실상, 기본적인 작업은 이것이 끝입니다. 이제 솔루션 탐색기에서 패키지 프로젝트를 우 클릭 후 "Publish" / "Create App Pacakges..." 메뉴를 선택하면 배포 파일을 만들 수 있습니다. 이 단계에서의 배포 방식이 2가지 유형으로 나뉘는데요,

"Microsoft Store under a new app name"을 선택하는 경우 여러분은 Microsoft Store에 개발자 등록 및 해당 앱을 등록하기 위한 몇 가지 단계를 거쳐야 합니다. 반면, Sideloading은 Microsoft Store를 거치지 않고 배포할 수 있는, 즉 기존의 ClickOnce 방식처럼 설치할 수 있는 방법을 제공합니다.

이에 관한 이력을 살짝 언급하자면, 원래 마이크로소프트는 Windows Store App을 철저하게 Microsoft Store를 통해서만 배포/관리가 되도록 강제를 했었습니다. 그런 정책은 점점 기업 고객들의 항의를 받게 되었는데요, 왜냐하면 다소 폐쇄된 기업 환경에서는 공개적인 Store를 통해 App을 배포하는 것이 여러 가지 이유로 불편했기 때문입니다. 따라서 전통적인 setup/msi 방식의 배포가 필요하게 되었고 이를 위해 마이크로소프트가 특별히 sideloading이라는 배포 방식을 지원하게 된 것입니다.

이 글에서는 제목에 따라 sideloading을 선택할 텐데요, 그럼 다시 몇 가지 질문이 제시된 후 해당 설치 파일이 위치할 경로를 지정하는 창이 나옵니다. 제 경우에는 다음의 URL로 지정했습니다.

Installer location: https://www.sysnet.pe.kr/temp/testappx

단계를 완료하면,

msix_pacakge_4.png

아래의 구조로 배포가 구성되는데,

C:\temp\consoleapp1\wapprojtemplate1\apppackages> tree . /F
Folder PATH listing for volume New Volume
Volume serial number is 00000086 4260:8239
C:\TEMP\CONSOLEAPP1\WAPPROJTEMPLATE1\APPPACKAGES
│   index.htmlWapProjTemplate1.appinstaller
│   
└───WapProjTemplate1_1.0.0.0_Debug_Test
    │   Add-AppDevPackage.ps1
    │   Install.ps1
    │   WapProjTemplate1_1.0.0.0_AnyCPU_Debug.appxsym
    │   WapProjTemplate1_1.0.0.0_AnyCPU_Debug.msixbundle
    │   
    ├───Add-AppDevPackage.resources
    │   │   Add-AppDevPackage.psd1
    │   │   
    │   ├───cs-CZ
    │   │       Add-AppDevPackage.psd1
    │   │       
...[생략]...
    │   │       
    │   └───zh-TW
    │           Add-AppDevPackage.psd1
    │           
    └───TelemetryDependencies
            LogSideloadingTelemetry.ps1
            Microsoft.VisualStudio.RemoteControl.dll
            Microsoft.VisualStudio.Telemetry.dll
            Microsoft.VisualStudio.Utilities.Internal.dll
            Newtonsoft.Json.dll

마치 기존의 ClickOnce를 보는 듯한 느낌입니다. (실제로 확장자 등의 차이점을 제외한다면 기존 ClickOnce의 동작 방식과 거의 유사합니다.)

여기서 가장 중요한 파일은 "WapProjTemplate1_1.0.0.0_AnyCPU_Debug.msixbundle"인데, 이것만 배포해 클라이언트 측에서 실행해 주면 App 설치가 완료됩니다. 단지, 그 과정을 쉽게 하기 위해 index.html, WapProjTemplate1.appinstaller 파일이 부차적으로 생성된 것인데요, 아무튼 이 파일들을 배포 빌드 과정에서 지정했던 "https://www.sysnet.pe.kr/temp/testappx" 경로에 해당하는 웹 서버로 올린 후, index.html을 방문하면 다음과 같은 화면을 보게 됩니다.

msix_pacakge_5.png

따라서 사용자는 좀 더 쉽게 웹 브라우저(또는 UNC 경로에 배포한 경우 탐색기)를 이용해 해당 페이지의 "Get the app" 버튼을 눌러 App을 설치할 수 있고, 그럼 시작 메뉴에 다음과 같이 App 아이콘이 등록되어 이후 자유롭게 실행할 수 있습니다.

msix_pacakge_6.png

App 업데이트도 ("Sideloading" 설정을 했을 때 함께 나오는 "Enable automatic updates" 옵션을 체크해 두었으면) 이후 클라이언트 측에서 App을 실행할 때마다 자동으로 업데이트 버전을 받게 됩니다.




index.html 좌측 하단의 "Additional Links"를 펼치면 3개의 링크가 나옵니다.

  1. Publisher Certificate
  2. App Installer File
  3. Package Bundle

인증서 링크의 경우, 해당 Application을 정식 인증 기관을 통해 서명 받은 인증서가 아닌 경우 대상 컴퓨터에 설치하기 위해 다운로드 하는 용도로 사용할 수 있습니다. App Installer File은 배포된 appinstaller 확장자의 파일을 다운로드할 수 있는 링크인데 이것만 다운로드한 후 로컬 컴퓨터의 PowerShell에서 "Add-AppxPackage -AppInstaller WapProjTemplate1.appinstaller" 명령을 통해 설치할 수 있습니다.

마지막으로 Package Bundle은 .msixbundle 파일에 대한 링크인데 사실상의 셋업 파일이므로 이 파일만 다운로드해 패키지를 로컬에 설치 후 실행하는 것이 가능합니다.

어떤가요? 기존의 ClickOnce 배포나 그 동작 방식과 매우 유사합니다. 한 가지 제약이라면 Windows 10을 대상으로 한 응용 프로그램만 배포할 수 있다는 점입니다.




자, 이제부터 ^^ 오류 메시지 정리입니다.

다른 컴퓨터에서 설치 도중 이런 오류가 발생한다면?

Cannot open app package

Reason: An error occurred while accessing the file from the web. Please try downloading and opening the file locally.

"Get the app" 버튼을 보면 다음과 같은 링크가 연결되는데,

ms-appinstaller:?source=https://...[생략].../temp/testappx/WapProjTemplate1.appinstaller

우선, 저 경로의 appinstaller 파일을 웹 브라우저로 방문해 다운로드가 되는지 확인해야 합니다. 일례로, 기본적인 IIS 설정으로는 appinstaller에 대한 다운로드를 지원하지 않기 때문인데요, 그런 경우 해당 파일이 다운로드가 가능하도록 IIS 설정에서 "MIME Types"에 해당 확장자를 등록해 열어줘야 합니다. 이에 관해서는 다음의 글을 참고하시고,

웹 사이트의 모든 정적 컨텐츠 요청에 대해 "Internal Server Error" 응답
; https://www.sysnet.pe.kr/2/0/1538#mime_register

IIS 7 - "MIME Types" 설정 아이콘이 없는 경우
; https://www.sysnet.pe.kr/2/0/1328

msix 배포를 위해서는 다음의 확장자를 등록하면 됩니다.

// https://learn.microsoft.com/en-us/windows/msix/app-installer/troubleshoot-appinstaller-issues#files-not-accessible

[필수]
.appinstaller - application/xml
.msixbundle - application/vns.ms-appx

[옵션]
.ps1 - application/octet-stream
.cer = application/x-x509-ca-cert
.psd1 = application/octet-stream
.appxsym = application/octet-stream




역시나 다른 컴퓨터에서 설치 도중 아래와 같은 오류를 만난다면?

This app package is not signed with a trusted certificate. Contact your system administrator or the app developer to obtain a new certificate or app package with trusted certificates. The root certificate and all immediate certificates of the signature in the app package must be trusted (0x800B010A)


여러분의 Package.appxmanifest에 Packaging 탭에서 지정한 인증서가 올바르게 서명된 인증서여야 합니다. 또는 테스트 인증서를 만든다면,

Troubleshoot installation issues with the App Installer file - Trusted certificates
; https://learn.microsoft.com/en-us/windows/msix/app-installer/troubleshoot-appinstaller-issues#trusted-certificates

New-SelfSignedCertificate -Type Custom -Subject "CN=Test" -KeyUsage DigitalSignature -FriendlyName "TestApp" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")

이 인증서를 App이 설치될 대상 컴퓨터의 certlm("Certificates - Local Computer") / "Trusted Root Certification Authorities"에 등록해 줘야 합니다.




다음과 같은 오류가 발생한다면?

App installation failed with error message: Appinstaller operation failed with error code 0x80D05011. Detail: Unknown error (0x80d05011)


PowerShell에서 appinstaller 파일을 다운로드해 설치해도 유사한 결과가 나옵니다.

PS C:\temp2> Add-AppxPackage -AppInstaller WapProjTemplate1.appinstaller
Add-AppxPackage : Deployment failed with HRESULT: 0x80D05011, The text associated with this error code could not be found.
Error message string not found
Appinstaller operation failed with error code 0x80D05011. Detail: Unknown error
NOTE: For additional information, look for [ActivityId] ddd1ebff-27da-000e-11d0-d8ddda27d701 in the Event Log or use the command line Get-App
PackageLog -ActivityID ddd1ebff-27da-000e-11d0-d8ddda27d701
At line:1 char:1
+ Add-AppxPackage -AppInstaller WapProjTemplate1.appinstaller
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (C:\temp2\WapProjTemplate1.appinstaller:String) [Add-AppxPackage], Exception
    + FullyQualifiedErrorId : DeploymentError,Microsoft.Windows.Appx.PackageManager.Commands.AddAppxPackageCommand

우선, 이에 대한 해결책은 발견하지 못했습니다. 단지, 이 오류가 발생하는 경우는 테스트 인증서를 등록해 사용하는 상황이었는데요, 정식 인증서를 사용하면 동일한 환경에서 0x80d05011 오류 없이 정상적으로 설치가 되었습니다.

따라서 이 오류를 만나게 되면 가능한 정식 인증서로 바꾸거나, 혹은 .msixbundle 파일을 다운로드 해 클라이언트에서 설치를 직접 하는 방법으로 해야 합니다. (물론, 그런 경우에는 등록된 http 경로를 통해 자동 업데이트가 되지 않습니다.)

(0x800B010A 오류의 원인을 아시는 분은 덧글 부탁드립니다. ^^)

(업데이트: 2021-04-07 - "AppInstaller XML Issue" 글에 보면 시스템을 재시작하면 된다고 하는데... ^^; 정말 됩니다. 아쉽게도 저는 테스트하지 못했지만 시스템 재시작이 아닌, "DoSvc(Delivery Optimization)" 서비스를 재시작해도 된다고 합니다.)




다음과 같은 오류가 발생한다면?

App installation failed with error message: error 0xC00CEE23: The XML in the .appinstaller file is not valid: Line 14, Column 11, Reason: '>' expected. (0xc00cee23)


이상하군요, 분명히 appinstaller 파일의 XML 문법은 유효한데 저런 오류가 발생합니다. appinstaller 파일을 다운로드해 Add-AppxPackage로 해도 유사한 오류가 발생합니다.

PS C:\temp2> Add-AppxPackage -AppInstaller WapProjTemplate1.appinstaller
Add-AppxPackage : Deployment failed with HRESULT: 0x8008020C, The .appinstaller file is invalid.
The .appinstaller file is invalid.
error 0xC00CEE23: The XML in the .appinstaller file is not valid: Line 14, Column 11, Reason: '>' expected.
NOTE: For additional information, look for [ActivityId] ddd1ebff-27da-0004-f164-d4ddda27d701 in the Event Log or use the command line Get-App
PackageLog -ActivityID ddd1ebff-27da-0004-f164-d4ddda27d701
At line:1 char:1
+ Add-AppxPackage -AppInstaller WapProjTemplate1.appinstaller
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (C:\temp2\WapPro...e1.appinstaller:String) [Add-AppxPackage], Exception
    + FullyQualifiedErrorId : DeploymentError,Microsoft.Windows.Appx.PackageManager.Commands.AddAppxPackageCommand

테스트를 해 보면, App의 버전이 1.0.9.0까지 일 때는 괜찮은데, 1.0.10.0으로 버전 숫자가 2자리로 되는 시점부터 저런 오류가 발생합니다. 검색해 보면 아래와 같이 이슈가 있는데,

Error 0xC00CEE23 when Minor Version >= 10
; https://techcommunity.microsoft.com/t5/msix-deployment/error-0xc00cee23-when-minor-version-gt-10/m-p/1780808

아직도 버그 픽스가 안 되었군요. ^^; 딱히 해결책이 없고, 단지 우회 방법으로 1.1.0.0 등의 버전으로 변경해야 합니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 3/9/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2024-03-31 08시56분
정성태

[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13835정성태12/2/2024148오류 유형: 934. Azure - rm: cannot remove '...': Directory not empty
13834정성태11/29/2024515Windows: 275. C# - CUI 애플리케이션과 Console 윈도우 (Windows 10 미만의 Classic Console 모드인 경우)파일 다운로드1
13833정성태11/29/2024524개발 환경 구성: 737. Azure Web App에서 Scale-out으로 늘어난 리눅스 인스턴스에 SSH 접속하는 방법
13832정성태11/27/2024744Windows: 274. Windows 7부터 도입한 conhost.exe
13831정성태11/27/2024843Linux: 111. eBPF - BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_MAP_TYPE_RINGBUF에 대한 다양한 용어들
13830정성태11/25/2024976개발 환경 구성: 736. 파이썬 웹 앱을 Azure App Service에 배포하기
13829정성태11/25/2024839스크립트: 67. 파이썬 - Windows 버전에서 함께 설치되는 py.exe
13828정성태11/25/2024967개발 환경 구성: 735. Azure - 압축 파일을 이용한 web app 배포 시 디렉터리 구분이 안 되는 문제파일 다운로드1
13827정성태11/25/20241044Windows: 273. Windows 환경의 파일 압축 방법 (tar, Compress-Archive)
13826정성태11/21/20241122닷넷: 2313. C# - (비밀번호 등의) Console로부터 입력받을 때 문자열 출력 숨기기(echo 끄기)파일 다운로드1
13825정성태11/21/20241100Linux: 110. eBPF / bpf2go - BPF_RINGBUF_OUTPUT / BPF_MAP_TYPE_RINGBUF 사용법
13824정성태11/20/20241055Linux: 109. eBPF / bpf2go - BPF_PERF_OUTPUT / BPF_MAP_TYPE_PERF_EVENT_ARRAY 사용법
13823정성태11/20/20241044개발 환경 구성: 734. Ubuntu에 docker, kubernetes (k3s) 설치
13822정성태11/20/2024994개발 환경 구성: 733. Windbg - VirtualBox VM의 커널 디버거 연결 시 COM 포트가 없는 경우
13821정성태11/18/20241141Linux: 108. Linux와 Windows의 프로세스/스레드 ID 관리 방식
13820정성태11/18/20241093VS.NET IDE: 195. Visual C++ - C# 프로젝트처럼 CopyToOutputDirectory 항목을 추가하는 방법
13819정성태11/15/20241073Linux: 107. eBPF - libbpf CO-RE의 CONFIG_DEBUG_INFO_BTF 빌드 여부에 대한 의존성
13818정성태11/15/20241173Windows: 272. Windows 11 24H2 - sudo 추가
13817정성태11/14/20241065Linux: 106. eBPF / bpf2go - (BPF_MAP_TYPE_HASH) Map을 이용한 전역 변수 구현
13816정성태11/14/20241126닷넷: 2312. C#, C++ - Windows / Linux 환경의 Thread Name 설정파일 다운로드1
13815정성태11/13/20241068Linux: 105. eBPF - bpf2go에서 전역 변수 설정 방법
13814정성태11/13/20241146닷넷: 2311. C# - Windows / Linux 환경에서 Native Thread ID 가져오기파일 다운로드1
13813정성태11/12/20241033닷넷: 2310. .NET의 Rune 타입과 emoji 표현파일 다운로드1
13812정성태11/11/2024917오류 유형: 933. Active Directory - The forest functional level is not supported.
13811정성태11/11/2024960Linux: 104. Linux - COLUMNS 환경변수가 언제나 80으로 설정되는 환경
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...