.NET 및 Win32 앱과 게임은 종종 다양한 언어로 지역화되어 총 주소 지정 가능한 시장을 확장합니다. 앱 지역화의 가치 제안에 대한 자세한 내용은 세계화 및 지역화참조하세요. .NET 또는 Win32 앱 또는 게임을 .msix 또는 .appx 패키지로 패키징하면 리소스 관리 시스템을 활용하여 런타임 컨텍스트에 맞는 앱 리소스를 로드할 수 있습니다. 이 심층 항목에서는 이 기술에 대해 설명합니다.
기존 Win32 애플리케이션을 지역화하는 방법에는 여러 가지가 있지만 Windows 8에서는 프로그래밍 언어, 애플리케이션 유형 간에 작동하고 간단한 지역화 이상의 기능을 제공하는 새로운 리소스 관리 시스템을 도입했습니다. 이 시스템은 이 항목에서 "MRT"라고 합니다. 역사적으로 그것은 "현대 자원 기술"을 의미했지만, "현대"라는 용어는 더 이상 사용되지 않게 되었습니다. 리소스 관리자는 MRM(최신 리소스 관리자) 또는 PRI(패키지 리소스 인덱스)라고도 합니다.
MSIX 기반 또는 .appx 기반 배포(예: Microsoft Store)와 결합된 MRT는 애플리케이션의 다운로드 및 설치 크기를 최소화하는 지정된 사용자/디바이스에 가장 적합한 리소스를 자동으로 제공할 수 있습니다. 이러한 크기 감소는 지역화된 콘텐츠가 많은 애플리케이션에서 AAA 게임의 경우 몇 기가바이트에 달할 정도로 중요할 수 있습니다. MRT의 추가 이점에는 Windows Shell 및 Microsoft Store의 지역화된 목록, 사용자의 기본 설정 언어가 사용 가능한 리소스와 일치하지 않는 경우 자동 대체 논리가 포함됩니다.
이 문서에서는 MRT의 고급 아키텍처를 설명하고 최소한의 코드 변경으로 레거시 Win32 애플리케이션을 MRT로 이동하는 데 도움이 되는 포팅 가이드를 제공합니다. MRT로 이동하면 개발자가 추가적인 이점(예: 배율 인수 또는 시스템 테마별로 리소스를 분할하는 기능)을 사용할 수 있게 됩니다. MRT 기반 지역화는 데스크톱 브리지(일명 "Centennial")에서 처리된 UWP 애플리케이션과 Win32 애플리케이션 모두에서 작동합니다.
대부분의 경우 런타임에 리소스를 확인하고 다운로드 크기를 최소화하기 위해 MRT와 통합하는 동시에 기존 지역화 형식 및 소스 코드를 계속 사용할 수 있습니다. 이는 전부 또는 전혀 사용되지 않는 방법이 아닙니다. 다음 표에는 각 단계의 작업 및 예상 비용/혜택이 요약되어 있습니다. 이 표에는 고해상도 또는 고대비 애플리케이션 아이콘 제공과 같은 비 지역화 작업이 포함되지 않습니다. 타일, 아이콘 등에 여러 자산을 제공하는 방법에 대한 더 자세한 정보는 언어별, 크기 조정, 고대비 및 기타 한정자에 맞게 리소스를 조정하는 방법을참조하세요.
일하다 | 이익 | 예상 비용 |
---|---|---|
패키지 매니페스트 지역화 | 지역화된 콘텐츠가 Windows Shell 및 Microsoft Store에 표시되도록 하는 데 필요한 최소 작업 | 소형 |
MRT를 사용하여 리소스 식별 및 찾기 | 다운로드 및 설치 크기를 최소화하기 위한 필수 조건 자동 언어 대체 | 미디엄 |
리소스 팩 빌드 | 다운로드 및 설치 크기를 최소화하는 마지막 단계 | 소형 |
MRT 리소스 형식 및 API로 마이그레이션 | 훨씬 더 작은 파일 크기(기존 리소스 기술에 따라 다름) | 크다 |
소개
대부분의 사소한 애플리케이션에는 애플리케이션의 코드에서 분리되는
따라서 리소스 관리 기술의 주요 목적은 런타임에 논리 또는 기호화된
예시
다음은 두 단추(및openButton
)에 텍스트 레이블이 있고 로고(saveButton
logoImage
)에 사용되는 PNG 파일이 있는 애플리케이션의 간단한 예입니다. 텍스트 레이블은 영어와 독일어로 지역화되며 로고는 일반 데스크톱 디스플레이(100개% 배율 인수) 및 고해상도 휴대폰(300개% 배율 인수)에 최적화되어 있습니다. 이 다이어그램은 모델에 관한 고급 개념의 보기를 제공함을 유의하십시오. 이는 구현과 정확히 일치하지 않습니다.
그래픽에서 애플리케이션 코드는 세 개의 논리 리소스 이름을 참조합니다. 런타임에 GetResource
가상 함수는 MRT를 사용하여 리소스 테이블(PRI 파일이라고 함)에서 해당 리소스 이름을 조회하여 주변 조건(사용자의 언어 및 디스플레이의 배율)에 따라 가장 적합한 후보를 찾습니다. 레이블의 경우 문자열이 직접 사용됩니다. 로고 이미지의 경우 문자열은 파일 이름으로 해석되고 파일은 디스크에서 읽습니다.
사용자가 영어 또는 독일어가 아닌 다른 언어를 사용하거나 화면 배율 인수가 100% 나 300%이 아닌 경우, MRT는 대체 규칙 집합에 따라 "가장 가까운" 일치 후보를 선택합니다(자세한 내용은 리소스 관리 시스템 참조).
참고로 MRT는 둘 이상의 한정자에 맞춤형으로 제공되는 리소스를 지원합니다. 예를 들어, 로고 이미지에 현지화해야 하는 텍스트가 포함된 경우, 로고의 후보는 EN/Scale-100, DE/Scale-100, EN/Scale-300, DE/Scale-300의 네 가지가 될 수 있습니다.
이 문서의 항목
다음 섹션에서는 MRT를 애플리케이션과 통합하는 데 필요한 개략적인 작업을 간략하게 설명합니다.
0단계: 애플리케이션 패키지 빌드
이 섹션에서는 기존 데스크톱 애플리케이션 빌드를 애플리케이션 패키지로 가져오는 방법을 간략하게 설명합니다. 이 단계에서는 MRT 기능이 사용되지 않습니다.
1단계: 애플리케이션 매니페스트 지역화
이 섹션에서는 레거시 리소스 형식 및 API를 사용하여 리소스를 패키지하고 찾는 동안 애플리케이션의 매니페스트를 지역화하는 방법을 간략하게 설명합니다(Windows 셸에 올바르게 표시됨).
2단계: MRT를 사용하여 리소스 식별 및 찾기
이 섹션에서는 기존 리소스 형식 및 API를 사용하여 리소스를 로드하고 사용하는 동시에 MRT를 사용하여 리소스를 찾기 위해 애플리케이션 코드(및 리소스 레이아웃)를 수정하는 방법을 간략하게 설명합니다.
3단계: 리소스 팩 빌드
이 섹션에서는 리소스를 별도의 리소스 팩으로 분리하는 데 필요한 최종 변경 내용을 간략하게 설명하여 앱의 다운로드(및 설치) 크기를 최소화합니다.
이 문서에서 다루지 않음
위의 0-3단계를 완료하면 Microsoft Store에 제출할 수 있는 애플리케이션 "번들"이 있으며, 필요하지 않은 리소스(예: 말하지 않는 언어)를 생략하여 사용자의 다운로드 및 설치 크기를 최소화할 수 있습니다. 애플리케이션 크기 및 기능의 추가 개선은 마지막 한 단계를 통해 수행할 수 있습니다.
4단계: MRT 리소스 형식 및 API로 마이그레이션
이 단계는 이 문서의 범위를 벗어나고 있습니다. MUI DLL 또는 .NET 리소스 어셈블리와 같은 레거시 형식에서 PRI 파일로 리소스(특히 문자열)를 이동해야 합니다. 이로 인해 다운로드 및 설치 크기가 추가로 절약될 수 있습니다. 또한 배율, 접근성 설정 등을 기반으로 이미지 파일의 다운로드 및 설치를 최소화하는 등 다른 MRT 기능을 사용할 수 있습니다.
0단계: 애플리케이션 패키지 빌드
애플리케이션의 리소스를 변경하기 전에 먼저 현재 패키징 및 설치 기술을 표준 UWP 패키징 및 배포 기술로 바꿔야 합니다. 이 작업을 수행하는 방법에는 세 가지가 있습니다.
- 복잡한 설치 관리자가 있는 대형 데스크톱 애플리케이션이 있거나 많은 OS 확장성 지점을 활용하는 경우 데스크톱 앱 변환기 도구를 사용하여 기존 앱 설치 관리자(예: MSI)에서 UWP 파일 레이아웃 및 매니페스트 정보를 생성할 수 있습니다.
- 비교적 적은 수의 파일이나 간단한 설치 관리자가 있고 확장성 후크가 없는 작은 데스크톱 애플리케이션이 있는 경우 파일 레이아웃 및 매니페스트 정보를 수동으로 만들 수 있습니다.
- 원본에서 다시 빌드하고 순수 UWP 애플리케이션으로 앱을 업데이트하려는 경우 Visual Studio에서 새 프로젝트를 만들고 IDE를 사용하여 많은 작업을 수행할 수 있습니다.
비고
데스크톱 앱 변환기는 더 이상 사용되지 않습니다. 새롭고 향상된 MSIX 패키징 도구를 사용하여 데스크톱 앱을 패키징하세요.
패키지를 수동으로 만들려면 애플리케이션의 모든 파일(실행 파일 및 콘텐츠는 포함하지만 소스 코드는 아님)과 패키지 매니페스트 파일(.appxmanifest)을 포함하는 디렉터리 구조를 만들어야 합니다. Hello, World GitHub 샘플
<?xml version="1.0" encoding="utf-8" ?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
<Identity Name="Contoso.Demo"
Publisher="CN=Contoso.Demo"
Version="1.0.0.0" />
<Properties>
<DisplayName>Contoso App</DisplayName>
<PublisherDisplayName>Contoso, Inc</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0"
MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="en-US" />
</Resources>
<Applications>
<Application Id="ContosoDemo" Executable="ContosoDemo.exe"
EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="Contoso Demo" BackgroundColor="#777777"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="Contoso Demo">
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
패키지 매니페스트 파일 및 패키지 레이아웃에 대한 자세한 내용은 앱 패키지 매니페스트를 참조하세요.
마지막으로 Visual Studio를 사용하여 새 프로젝트를 만들고 기존 코드를 마이그레이션하는 경우 "Hello, world" 앱 만들기를 참조하세요. 기존 코드를 새 프로젝트에 포함할 수 있지만 순수 UWP 앱으로 실행하려면 중요한 코드 변경(특히 사용자 인터페이스)을 수행해야 할 수 있습니다. 이러한 변경 내용은 이 문서의 범위를 벗어습니다.
1단계: 매니페스트 지역화
1.1단계: 매니페스트의 문자열 및 자산 업데이트
0단계에서는 애플리케이션에 대한 기본 패키지 매니페스트(.appxmanifest) 파일을 만들었지만(변환기에 제공된 값에 따라 MSI에서 추출되거나 매니페스트에 수동으로 입력됨) 지역화된 정보가 포함되지 않으며 고해상도 시작 타일 자산과 같은 추가 기능을 지원하지도 않습니다.
애플리케이션의 이름과 설명이 올바르게 지역화되었는지 확인하려면 리소스 파일 집합에 일부 리소스를 정의하고 해당 리소스를 참조하도록 패키지 매니페스트를 업데이트해야 합니다.
기본 리소스 파일 만들기
첫 번째 단계는 기본 언어(예: 미국 영어)로 기본 리소스 파일을 만드는 것입니다. 텍스트 편집기를 사용하여 수동으로 또는 Visual Studio의 리소스 디자이너를 통해 이 작업을 수행할 수 있습니다.
리소스를 수동으로 만들려는 경우:
- 이름이 지정된
resources.resw
XML 파일을 만들어 프로젝트의 하위 폴더에Strings\en-us
배치합니다. 기본 언어가 미국 영어가 아닌 경우 적절한 BCP-47 코드를 사용합니다. - XML 파일에서 다음 콘텐츠를 추가합니다. 여기에서 강조 표시된 텍스트 부분을 기본 언어로 된 앱에 적합한 텍스트로 교체합니다.
비고
이러한 문자열 중 일부의 길이에는 제한이 있습니다. 자세한 내용은 VisualElements를 참조하세요.
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ApplicationDescription">
<value>Contoso Demo app with localized resources (English)</value>
</data>
<data name="ApplicationDisplayName">
<value>Contoso Demo Sample (English)</value>
</data>
<data name="PackageDisplayName">
<value>Contoso Demo Package (English)</value>
</data>
<data name="PublisherDisplayName">
<value>Contoso Samples, USA</value>
</data>
<data name="TileShortName">
<value>Contoso (EN)</value>
</data>
</root>
Visual Studio에서 디자이너를 사용하려는 경우:
-
Strings\en-us
프로젝트에서 폴더(또는 적절한 다른 언어)를 만들고 기본 이름을 사용하여 프로젝트의 루트 폴더에resources.resw
추가합니다. 리소스 파일(.resw)을 선택하고 리소스 사전을 선택하지 않도록 하세요. 리소스 사전은 XAML 애플리케이션에서 사용하는 파일입니다. - 디자이너를 사용하여 다음 문자열을 입력합니다(동일하게
Names
사용하지만 애플리케이션에Values
적합한 텍스트로 바꿈).
비고
Visual Studio 디자이너로 시작하는 경우 언제든지 키를 눌러 F7
XML을 직접 편집할 수 있습니다. 그러나 최소 XML 파일로 시작하는 경우 추가 메타데이터가 많이 누락되었으므로 디자이너가 파일을 인식하지 않습니다. 디자이너에서 생성된 파일의 상용구 XSD 정보를 직접 편집한 XML 파일로 복사하여 이 문제를 해결할 수 있습니다.
리소스를 참조하도록 매니페스트 업데이트
파일에 정의된 값이 .resw
있으면 다음 단계는 리소스 문자열을 참조하도록 매니페스트를 업데이트하는 것입니다. XML 파일을 직접 편집하거나 Visual Studio 매니페스트 디자이너를 사용할 수도 있습니다.
XML을 직접 편집하는 경우 .resw
것과 정확히 일치해야 합니다. 이러한 이름은 Names
파일에서 만든 .resw
일치해야 하며 ms-resource:
체계 및 Resources/
네임스페이스가 접두사로 지정됩니다.
비고
매니페스트의 많은 요소가 이 코드 조각에서 생략되었습니다. 아무것도 삭제하지 마세요!
<?xml version="1.0" encoding="utf-8"?>
<Package>
<Properties>
<DisplayName>ms-resource:Resources/PackageDisplayName</DisplayName>
<PublisherDisplayName>ms-resource:Resources/PublisherDisplayName</PublisherDisplayName>
</Properties>
<Applications>
<Application>
<uap:VisualElements DisplayName="ms-resource:Resources/ApplicationDisplayName"
Description="ms-resource:Resources/ApplicationDescription">
<uap:DefaultTile ShortName="ms-resource:Resources/TileShortName">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo" />
</uap:ShowNameOnTiles>
</uap:DefaultTile>
</uap:VisualElements>
</Application>
</Applications>
</Package>
Visual Studio 매니페스트 디자이너를 사용하는 경우 .appxmanifest 파일을 열고 *애플리케이션 탭 및 패키징 탭에서 강조 표시된 값 값을 변경합니다.
1.2단계: PRI 파일 빌드, MSIX 패키지 만들기, 작동하는지 확인
이제 파일을 빌드 .pri
하고 애플리케이션을 배포하여 시작 메뉴에 올바른 정보(기본 언어)가 표시되는지 확인할 수 있습니다.
Visual Studio에서 빌드하는 경우 간단히 눌러 Ctrl+Shift+B
프로젝트를 빌드한 다음 프로젝트를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 선택합니다 Deploy
.
수동으로 빌드하는 경우 다음 단계에 따라 도구에 대한 MakePRI
구성 파일을 만들고 파일 자체를 생성 .pri
합니다( 자세한 내용은 수동 앱 패키징에서 찾을 수 있음).
시작 메뉴의 Visual Studio 2019 또는 VisualStudio 2022 폴더에서 개발자 명령 프롬프트를 엽니다.
프로젝트 루트 디렉터리(.appxmanifest 파일 및 Strings 폴더를 포함하는 디렉터리)로 전환합니다.
다음 명령을 입력하여 "contoso_demo.xml"을 프로젝트에 적합한 이름으로 바꿉니다. "en-US"을 앱의 기본 언어로 바꿉니다(또는 해당하는 경우 en-US 유지). XML 파일은 애플리케이션의 일부가 아니므로 부모 디렉터리(프로젝트 디렉터리에 없음 )에 만들어집니다(원하는 다른 디렉터리를 선택할 수 있지만 이후 명령에서 대체해야 합니다).
makepri createconfig /cf ..\contoso_demo.xml /dq en-US /pv 10.0 /o
입력
makepri createconfig /?
하여 각 매개 변수가 수행하는 작업을 확인할 수 있지만 요약하면 다음과 같습니다.-
/cf
구성 파일 이름(이 명령의 출력)을 설정합니다. -
/dq
은(는) 기본 한정자를 설정하며, 이 경우 언어는en-US
입니다. -
/pv
플랫폼 버전(이 경우 Windows 10)을 설정합니다. -
/o
는 출력 파일이 있는 경우 출력 파일을 덮어쓰도록 설정합니다.
-
이제 구성 파일이 있으므로 다시 실행
MakePRI
하여 실제로 디스크에서 리소스를 검색하고 PRI 파일로 패키지합니다. "contoso_demop.xml"을 이전 단계에서 사용한 XML 파일 이름으로 바꾸고 입력 및 출력 모두에 대한 부모 디렉터리를 지정해야 합니다.makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /o
입력
makepri new /?
하여 각 매개 변수가 수행하는 작업을 확인할 수 있지만 간단히 말해서 다음을 수행합니다.-
/pr
프로젝트 루트를 설정합니다(이 경우 현재 디렉터리). -
/cf
이전 단계에서 만든 구성 파일 이름을 설정합니다. -
/of
은 출력 파일을 설정합니다 -
/mf
매핑 파일을 만듭니다(이후 단계에서 패키지에서 파일을 제외할 수 있도록). -
/o
는 출력 파일이 있는 경우 출력 파일을 덮어쓰도록 설정합니다.
-
.pri
이제 기본 언어 리소스(예: en-US)가 있는 파일이 있습니다. 제대로 작동하는지 확인하려면 다음 명령을 실행할 수 있습니다.makepri dump /if ..\resources.pri /of ..\resources /o
입력
makepri dump /?
하여 각 매개 변수가 수행하는 작업을 확인할 수 있지만 간단히 말해서 다음을 수행합니다.-
/if
입력 파일 이름을 설정합니다. -
/of
출력 파일 이름을 설정합니다(.xml
자동으로 추가됨). -
/o
는 출력 파일이 있는 경우 출력 파일을 덮어쓰도록 설정합니다.
-
마지막으로
..\resources.xml
을(를) 텍스트 편집기에서 열고, 그것이<NamedResource>
값을 나열하는지 확인할 수 있습니다. 이때 선택한 기본 언어의ApplicationDescription
값과 함께,PublisherDisplayName
및<Candidate>
같은 값이 포함되어야 합니다. (파일의 시작 부분에는 다른 콘텐츠가 있으니, 지금은 무시하십시오.)
매핑 파일을 ..\resources.map.txt
열어 프로젝트에 필요한 파일(프로젝트 디렉터리의 일부가 아닌 PRI 파일 포함)이 포함되어 있는지 확인할 수 있습니다. 중요한 것은 해당 파일의 내용이 PRI 파일에 이미 포함되어 있으므로 매핑 파일에는 파일에 대한 참조가 포함되지 않을 것입니다 resources.resw
. 그러나 이미지 파일 이름과 같은 다른 추가 리소스도 포함될 것입니다.
패키지 빌드 및 서명
이제 PRI 파일이 빌드되어 패키지를 빌드하고 서명할 수 있습니다.
앱 패키지를 만들려면 다음 명령을 실행하여
만들려는 .msix/.appx 파일의 이름으로 대체하고 파일에 대해 다른 디렉터리를 선택해야 합니다(이 샘플은 부모 디렉터리를 사용하며, 어디에나 있을 수 있지만 프로젝트 디렉터리가 안 됩니다). makeappx pack /m AppXManifest.xml /f ..\resources.map.txt /p ..\contoso_demo.appx /o
입력
makeappx pack /?
하여 각 매개 변수가 수행하는 작업을 확인할 수 있지만 간단히 말해서 다음을 수행합니다.-
/m
사용할 매니페스트 파일을 설정합니다. -
/f
사용할 매핑 파일을 설정합니다(이전 단계에서 만든). -
/p
출력 패키지 이름을 설정합니다. -
/o
는 출력 파일이 있는 경우 출력 파일을 덮어쓰도록 설정합니다.
-
패키지를 만든 후에는 서명해야 합니다. 서명 인증서를 가장 쉽게 얻는 방법은 Visual Studio에서 빈 유니버설 Windows 프로젝트를 생성하고 생성된
.pfx
파일을 복사하는 것입니다. 그러나MakeCert
에서 설명된 대로Pvk2Pfx
및 유틸리티를 사용하여 수동으로 만들 수도 있습니다.중요합니다
서명 인증서를 수동으로 만드는 경우 원본 프로젝트 또는 패키지 원본과 다른 디렉터리에 파일을 배치해야 합니다. 그렇지 않으면 프라이빗 키를 포함하여 패키지의 일부로 포함될 수 있습니다.
패키지에 서명하려면 다음 명령을 사용합니다.
Publisher
은Identity
의AppxManifest.xml
요소에 지정된 부분으로, 인증서의Subject
과 일치해야 합니다. 이는 사용자에게 표시할 지역화된 표시 이름인 요소의<PublisherDisplayName>
않는 것입니다. 평소와 같이 파일 이름을 프로젝트에 적합한 이름으로 바꾸고contoso_demo...
(매우 중요) 파일이 현재 디렉터리에 없는지 확인.pfx
합니다(그렇지 않으면 프라이빗 서명 키를 포함하여 패키지의 일부로 생성됨).signtool sign /fd SHA256 /a /f ..\contoso_demo_key.pfx ..\contoso_demo.appx
입력
signtool sign /?
하여 각 매개 변수가 수행하는 작업을 확인할 수 있지만 간단히 말해서 다음을 수행합니다.-
/fd
파일 다이제스트 알고리즘을 설정합니다(SHA256은 .appx 기본값임). -
/a
는 자동으로 최상의 인증서를 선택합니다. -
/f
서명 인증서를 포함하는 입력 파일을 지정합니다.
-
마지막으로 파일을 두 번 클릭하여 .appx
설치하거나, 명령줄을 선호하는 경우 PowerShell 프롬프트를 열고, 패키지가 포함된 디렉터리로 변경하고, 다음을 입력합니다(패키지 이름으로 대체 contoso_demo.appx
).
add-appxpackage contoso_demo.appx
신뢰할 수 없는 인증서에 대한 오류가 표시되는 경우, 인증서가 컴퓨터 저장소에 추가되었는지 확인하세요. 사용자 저장소()가 아닌 기계 저장소(
명령줄을 사용하려면:
관리자 권한으로 Visual Studio 2019 또는 Visual Studio 2022 명령 프롬프트를 실행합니다.
파일이 포함된
.cer
디렉터리로 전환합니다(원본 또는 프로젝트 디렉터리 외부에 있는지 확인해야 합니다.)contoso_demo.cer
을(를) 파일 이름으로 바꿔서 다음 명령을 입력하세요.certutil -addstore TrustedPeople contoso_demo.cer
실행
certutil -addstore /?
하여 각 매개 변수가 수행하는 작업을 확인할 수 있지만 간단히 말해서 다음을 수행합니다.-
-addstore
은 인증서를 인증서 저장소에 추가합니다. -
TrustedPeople
은 인증서가 배치되는 저장소를 나타냅니다.
-
Windows 탐색기를 사용하려면 다음을 수행합니다.
-
.pfx
파일이 포함된 폴더로 이동하세요. - 파일을 두 번 클릭하면
.pfx
인증서 가져오기 마법사 가 표시됩니다. - 선택
Local Machine
및 클릭Next
- 사용자 계정 컨트롤 관리자 권한 상승 프롬프트가 표시되면 이를 수락한 후
Next
을(를) 클릭하세요. - 프라이빗 키에 대한 암호가 있는 경우 입력하고,
Next
를 클릭하세요. -
Place all certificates in the following store
선택하세요 -
Browse
을 클릭하고Trusted People
폴더를 선택합니다(“신뢰할 수 있는 게시자”가 아닌). -
Next
클릭한 다음Finish
저장소에 인증서를 추가한 Trusted People
후 패키지를 다시 설치해 봅니다.
이제 앱이 시작 메뉴의 "모든 앱" 목록에 표시되고 .resw
/ .pri
파일의 올바른 정보가 표시됩니다. 빈 문자열이나 문자열 ms-resource:...
이 표시되면 문제가 발생했습니다. 편집 내용을 다시 확인하고 올바른지 확인합니다. 시작 메뉴에서 앱을 마우스 오른쪽 단추로 클릭하면 타일로 고정하고 올바른 정보가 표시되는지 확인할 수 있습니다.
1.3단계: 지원되는 언어 추가
패키지 매니페스트를 변경하고 초기 resources.resw
파일을 만든 후에는 추가 언어를 쉽게 추가할 수 있습니다.
추가 지역화된 리소스 만들기
먼저 추가 지역화된 리소스 값을 만듭니다.
Strings
폴더 내에서 적절한 BCP-47 코드(예Strings\de-DE
: )를 사용하여 지원하는 각 언어에 대한 추가 폴더를 만듭니다. 이러한 각 폴더 내에 번역된 리소스 값을 포함하는 resources.resw
파일(XML 편집기 또는 Visual Studio 디자이너 사용)을 만드십시오. 이미 지역화된 문자열이 어딘가에 있다고 가정하고, 그것을 .resw
파일에 복사하기만 하면 됩니다. 이 문서에서는 번역 과정을 자체적으로 다루지 않습니다.
예를 들어 Strings\de-DE\resources.resw
파일은 로 변경된 상태로 다음과 같을 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ApplicationDescription">
<value>Contoso Demo app with localized resources (German)</value>
</data>
<data name="ApplicationDisplayName">
<value>Contoso Demo Sample (German)</value>
</data>
<data name="PackageDisplayName">
<value>Contoso Demo Package (German)</value>
</data>
<data name="PublisherDisplayName">
<value>Contoso Samples, DE</value>
</data>
<data name="TileShortName">
<value>Contoso (DE)</value>
</data>
</root>
다음 단계에서는 de-DE
와 fr-FR
둘 다에 대한 리소스를 추가했다고 가정합니다. 하지만 이와 동일한 패턴을 어떤 언어에 대해서도 따를 수 있습니다.
지원되는 언어를 나열하도록 패키지 매니페스트 업데이트
앱에서 지원하는 언어를 나열하도록 패키지 매니페스트를 업데이트해야 합니다. 데스크톱 앱 변환기는 기본 언어를 추가하지만 다른 언어는 명시적으로 추가해야 합니다.
<Resources>
<Resource Language="EN-US" />
<Resource Language="DE-DE" />
<Resource Language="FR-FR" />
</Resources>
Visual Studio를 사용하는 경우 아무 것도 할 필요가 없습니다. Package.appxmanifest
을 살펴보면 특수 x-generate 값이 표시될 것입니다. 이는 빌드 프로세스가 BCP-47 코드로 명명된 폴더에 따라 프로젝트에서 발견한 언어를 삽입하게 합니다. 이는 실제 패키지 매니페스트에 유효한 값이 아닙니다. Visual Studio 프로젝트에만 작동합니다.
<Resources>
<Resource Language="x-generate" />
</Resources>
지역화된 값을 사용하여 다시 빌드
이제 애플리케이션을 다시 빌드하고 배포할 수 있으며 Windows에서 언어 기본 설정을 변경하면 새로 지역화된 값이 시작 메뉴에 표시됩니다(언어를 변경하는 방법에 대한 지침은 아래 참조).
Visual Studio의 경우, Ctrl+Shift+B
을 사용하여 빌드를 하고, 프로젝트를 마우스 오른쪽 버튼으로 클릭하여 Deploy
을 할 수 있습니다.
프로젝트를 수동으로 빌드하는 경우 위와 동일한 단계를 수행하지만 구성 파일을 만들 때 밑줄로 구분된 추가 언어를 기본 한정자 목록(/dq
)에 추가합니다. 예를 들어 이전 단계에서 추가된 영어, 독일어 및 프랑스어 리소스를 지원하려면 다음을 수행합니다.
makepri createconfig /cf ..\contoso_demo.xml /dq en-US_de-DE_fr-FR /pv 10.0 /o
이렇게 하면 테스트에 쉽게 사용할 수 있는 지정된 모든 언어가 포함된 PRI 파일이 생성됩니다. 리소스의 총 크기가 작거나 적은 수의 언어만 지원하는 경우, 이것이 배송 앱에 허용될 수도 있습니다. 리소스의 설치/다운로드 크기를 최소화하는 이점을 원할 경우에만 별도의 언어 팩을 빌드하는 추가 작업을 수행해야 합니다.
지역화된 값으로 테스트
지역화된 새 변경 내용을 테스트하려면 Windows에 새 기본 설정 UI 언어를 추가하기만 하면 됩니다. 언어 팩을 다운로드하거나, 시스템을 다시 부팅하거나, 전체 Windows UI를 외국어로 표시할 필요가 없습니다.
-
Settings
앱 실행(Windows + I
) -
Time & language
으로 이동 -
Region & language
으로 이동 -
Add a language
을 클릭합니다. - 원하는 언어를 입력(예:
Deutsch
또는German
선택)합니다.- 하위 언어가 있는 경우 원하는 언어를 선택합니다(예:
Deutsch / Deutschland
).
- 하위 언어가 있는 경우 원하는 언어를 선택합니다(예:
- 언어 목록에서 새 언어 선택
-
Set as default
을 클릭합니다.
이제 시작 메뉴를 열고 애플리케이션을 검색하면 선택한 언어에 대한 지역화된 값이 표시됩니다(다른 앱도 지역화된 것으로 표시될 수 있습니다). 지역화된 이름이 바로 표시되지 않으면 시작 메뉴의 캐시를 새로 고칠 때까지 몇 분 정도 기다립니다. 모국어로 돌아가려면 언어 목록에서 기본 언어로 만드십시오.
1.4단계: 패키지 매니페스트의 더 많은 부분 지역화(선택 사항)
패키지 매니페스트의 다른 섹션을 지역화할 수 있습니다. 예를 들어, 애플리케이션이 파일 확장자를 처리하는 경우 매니페스트에 windows.fileTypeAssociation
확장명이 있어야 합니다. 녹색으로 강조 표시된 텍스트는 표시된 대로 정확히(리소스를 참조하므로) 하고, 노란색으로 강조 표시된 텍스트를 애플리케이션 관련 정보로 교체합니다.
<Extensions>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="default">
<uap:DisplayName>ms-resource:Resources/FileTypeDisplayName</uap:DisplayName>
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
<uap:InfoTip>ms-resource:Resources/FileTypeInfoTip</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType ContentType="application/x-contoso">.contoso</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
</Extensions>
Visual Studio 매니페스트 디자이너에서 Declarations
탭과 강조 표시된 값을 참고하여 이 정보를 추가할 수도 있습니다.
이제 각 .resw
파일에 해당하는 리소스 이름을 추가하고, 강조 표시된 텍스트를 앱에 적합한 텍스트로 바꿉니다(지원되는 각 언어에 대해 이 작업을 수행해야 합니다 .).
... existing content...
<data name="FileTypeDisplayName">
<value>Contoso Demo File</value>
</data>
<data name="FileTypeInfoTip">
<value>Files used by Contoso Demo App</value>
</data>
그러면 파일 탐색기 같은 Windows 셸의 일부에 표시됩니다.
이전과 같이 패키지를 빌드하고 테스트하여 새 UI 문자열을 표시해야 하는 새 시나리오를 실행합니다.
2단계: MRT를 사용하여 리소스 식별 및 찾기
이전 섹션에서는 MRT를 사용하여 앱의 매니페스트 파일을 지역화하는 방법을 보여 주었기 때문에 Windows Shell에서 앱의 이름 및 기타 메타데이터를 올바르게 표시할 수 있습니다. 이에 대한 코드 변경이 필요하지 않았습니다. .resw
파일과 몇 가지 추가 도구를 단순히 사용해야 했습니다. 이 섹션에서는 MRT를 사용하여 기존 리소스 형식으로 리소스를 찾고 최소한의 변경으로 기존 리소스 처리 코드를 사용하는 방법을 보여 줍니다.
기존 파일 레이아웃 및 애플리케이션 코드에 대한 가정
Win32 Desktop 앱을 지역화하는 방법에는 여러 가지가 있기 때문에 이 문서에서는 특정 환경에 매핑해야 하는 기존 애플리케이션의 구조에 대한 몇 가지 단순화된 가정을 만듭니다. MRT의 요구 사항을 준수하기 위해 기존 코드베이스 또는 리소스 레이아웃을 일부 변경해야 할 수 있으며 이 문서의 범위가 크게 벗어났습니다.
리소스 파일 레이아웃
이 문서에서는 지역화된 리소스가 모두 동일한 파일 이름(예: contoso_demo.exe.mui
또는 contoso_strings.dll
contoso.strings.xml
)을 가지지만 BCP-47 이름(en-US
de-DE
등)이 있는 다른 폴더에 배치된다고 가정합니다. 리소스 파일의 수, 이름, 파일 형식/관련 API 등은 중요하지 않습니다. 중요한 것은 모든 논리 리소스의 파일 이름이 동일 하지만 다른 물리적 디렉터리에 배치된다는 것입니다.
반대로 애플리케이션이 파일을 Resources
english_strings.dll
포함하는 단일 french_strings.dll
디렉터리가 있는 플랫 파일 구조를 사용하는 경우 MRT에 잘 매핑되지 않습니다. 더 나은 구조는 Resources
디렉터리가 하위 디렉터리 및 파일 en\strings.dll
과 fr\strings.dll
를 포함하는 것입니다. 동일한 기본 파일 이름을 포함 한정자, 예를 들어 strings.lang-en.dll
및 strings.lang-fr.dll
와 함께 사용하는 것도 가능하지만, 언어 코드가 있는 디렉터리를 사용하는 것이 개념적으로 더 간단하므로 이에 집중하겠습니다.
비고
이 파일 명명 규칙을 따를 수 없는 경우에도 MRT 및 패키징의 이점을 사용할 수 있습니다. 그것은 단지 더 많은 작업이 필요합니다.
예를 들어 애플리케이션에는 UICommands 폴더 아래에 배치된 ui.txt이라는 간단한 텍스트 파일에 사용자 지정 UI 명령 집합(단추 레이블 등에 사용됨)이 있을 수 있습니다.
+ ProjectRoot |--+ Strings | |--+ en-US | | \--- resources.resw | \--+ de-DE | \--- resources.resw |--+ UICommands | |--+ en-US | | \--- ui.txt | \--+ de-DE | \--- ui.txt |--- AppxManifest.xml |--- ...rest of project...
리소스 로드 코드
이 문서에서는 코드의 어느 시점에서 지역화된 리소스가 포함된 파일을 찾아 로드한 다음 사용하려는 것으로 가정합니다. 리소스를 로드하는 데 사용되는 API, 리소스를 추출하는 데 사용되는 API 등은 중요하지 않습니다. 의사코드에는 세 가지 단계가 있습니다.
set userLanguage = GetUsersPreferredLanguage() set resourceFile = FindResourceFileForLanguage(MY_RESOURCE_NAME, userLanguage) set resource = LoadResource(resourceFile) // now use 'resource' however you want
MRT는 이 프로세스에서 가장 적합한 후보 리소스를 결정하는 방법과 리소스를 찾는 방법의 처음 두 단계만 변경하면 됩니다. 리소스를 로드하거나 사용하는 방법을 변경할 필요는 없습니다(리소스를 활용하려는 경우 이를 위한 기능을 제공하지만).
예를 들어 애플리케이션은 Win32 API GetUserPreferredUILanguages
, CRT 함수 sprintf
및 Win32 API CreateFile
를 사용하여 위의 세 가지 의사 코드 함수를 바꾼 다음, 수동으로 텍스트 파일을 구문 분석하여 name=value
쌍을 찾을 수 있습니다. (세부 정보는 중요하지 않습니다. 이는 MRT가 리소스를 배치한 후 처리하는 데 사용되는 기술에 영향을 미치지 않음을 설명하기 위한 것일 뿐입니다).
2.1단계: MRT를 사용하여 파일을 찾기 위한 코드 변경
리소스를 찾기 위해 MRT를 사용하도록 코드를 전환하는 것은 어렵지 않습니다. 소수의 WinRT 형식과 몇 줄의 코드를 사용해야 합니다. 사용할 기본 형식은 다음과 같습니다.
- ResourceContext은 현재 활성화된 한정자 값 집합(언어, 배율 인수 등)을 포함합니다.
- PRI 파일의 모든 리소스에 액세스할 수 있는 ResourceManager(.NET 버전이 아닌 WinRT 버전)
- PRI 파일의 특정 리소스 하위 집합을 나타내는 ResourceMap(이 예제에서는 파일 기반 리소스와 문자열 리소스)
- "NamedResource" 는 논리 리소스와 가능한 모든 후보를 나타냅니다.
- 단일 구체적인 후보 리소스를 나타내는 ResourceCandidate
의사코드에서 주어진 리소스 파일 이름(예: 위 샘플의 UICommands\ui.txt
)을 해결하는 방법은 다음과 같습니다.
// Get the ResourceContext that applies to this app set resourceContext = ResourceContext.GetForViewIndependentUse() // Get the current ResourceManager (there's one per app) set resourceManager = ResourceManager.Current // Get the "Files" ResourceMap from the ResourceManager set fileResources = resourceManager.MainResourceMap.GetSubtree("Files") // Find the NamedResource with the logical filename we're looking for, // by indexing into the ResourceMap set desiredResource = fileResources["UICommands\ui.txt"] // Get the ResourceCandidate that best matches our ResourceContext set bestCandidate = desiredResource.Resolve(resourceContext) // Get the string value (the filename) from the ResourceCandidate set absoluteFileName = bestCandidate.ValueAsString
특히 코드는 디스크에 파일이 있는 경우에도 UICommands\ui.txt
을 요청한 다음, MRT를 사용하여 언어 디렉터리 중 하나에서 적절한 디스크 내 파일을 찾습니다.
여기서 샘플 앱은 CreateFile
을 사용하여 계속해서 absoluteFileName
을 로드하고 이전과 마찬가지로 name=value
쌍을 구문 분석할 수 있습니다. 앱에서 그 논리를 변경할 필요는 없습니다. C# 또는 C++/CX로 작성하는 경우 실제 코드는 이보다 훨씬 복잡하지 않습니다(실제로 많은 중간 변수를 제외할 수 있습니다). 아래 .NET 리소스 로드 섹션을 참조하세요. C++/WRL 기반 애플리케이션은 WinRT API를 활성화하고 호출하는 데 사용되는 하위 수준 COM 기반 API로 인해 더 복잡하지만 수행하는 기본 단계는 동일합니다. 아래 Win32 MUI 리소스 로드 섹션을 참조하세요.
.NET 리소스 로드
.NET에는 리소스를 찾아서 로드하기 위한 기본 제공 메커니즘("위성 어셈블리"라고 함)이 있으므로 위의 가상 예제와 같이 대체할 명시적 코드가 없습니다. .NET에서는 적절한 디렉터리에 리소스 DLL만 있으면 자동으로 배치됩니다. 앱이 리소스 팩을 사용하여 MSIX 또는 .appx로 패키지될 경우, 디렉터리 구조는 다소 다릅니다. 리소스 디렉터리가 주 애플리케이션 디렉터리의 하위 디렉터리가 아니라 그것과 동등한 수준에 위치하거나, 사용자의 기본 설정에 언어가 나열되어 있지 않다면 아예 존재하지 않을 수도 있습니다.
예를 들어 폴더 아래에 모든 파일이 있는 다음 레이아웃이 있는 .NET 애플리케이션을 가정해 MainApp
보겠습니다.
+ MainApp |--+ en-us | \--- MainApp.resources.dll |--+ de-de | \--- MainApp.resources.dll |--+ fr-fr | \--- MainApp.resources.dll \--- MainApp.exe
appx로 변환한 후, en-US
가 기본 언어로 설정되어 있고 사용자가 독일어와 프랑스어를 언어 목록에 모두 나열한 경우, 레이아웃은 다음과 같이 표시됩니다.
+ WindowsAppsRoot |--+ MainApp_neutral | |--+ en-us | | \--- MainApp.resources.dll | \--- MainApp.exe |--+ MainApp_neutral_resources.language_de | \--+ de-de | \--- MainApp.resources.dll \--+ MainApp_neutral_resources.language_fr \--+ fr-fr \--- MainApp.resources.dll
지역화된 리소스가 주 실행 파일 설치 위치의 하위 디렉터리에 더 이상 없으므로, .NET 기본 리소스 확인이 실패합니다. 다행히 .NET에는 실패한 어셈블리 로드 시도(이벤트)를 처리하기 위한 잘 정의된 메커니즘이 AssemblyResolve
있습니다. MRT를 사용하는 .NET 앱은 이 이벤트에 등록하고 .NET 리소스 하위 시스템에 대한 누락된 어셈블리를 제공해야 합니다.
WinRT API를 사용하여 .NET에서 사용되는 위성 어셈블리를 찾는 방법에 대한 간결한 예는 다음과 같습니다. 제공된 코드는 위의 의사 코드와 밀접하게 매핑되며, 최소한의 구현을 보이기 위해 의도적으로 간소화되었습니다. 전달된 ResolveEventArgs
는 우리가 찾아야 할 어셈블리의 이름을 제공합니다. 이 코드의 실행 가능한 버전(자세한 설명 및 오류 처리 포함)은 GitHub
static class PriResourceResolver
{
internal static Assembly ResolveResourceDll(object sender, ResolveEventArgs args)
{
var fullAssemblyName = new AssemblyName(args.Name);
var fileName = string.Format(@"{0}.dll", fullAssemblyName.Name);
var resourceContext = ResourceContext.GetForViewIndependentUse();
resourceContext.Languages = new[] { fullAssemblyName.CultureName };
var resource = ResourceManager.Current.MainResourceMap.GetSubtree("Files")[fileName];
// Note use of 'UnsafeLoadFrom' - this is required for apps installed with .appx, but
// in general is discouraged. The full sample provides a safer wrapper of this method
return Assembly.UnsafeLoadFrom(resource.Resolve(resourceContext).ValueAsString);
}
}
위의 클래스를 고려할 때 애플리케이션의 시작 코드에서 초기에 다음을 추가합니다(지역화된 리소스를 로드하기 전에).
void EnableMrtResourceLookup()
{
AppDomain.CurrentDomain.AssemblyResolve += PriResourceResolver.ResolveResourceDll;
}
.NET 런타임은 리소스 DLL을 찾을 수 없을 때마다 이벤트를 발생 AssemblyResolve
시키고, 이때 제공된 이벤트 처리기는 MRT를 통해 원하는 파일을 찾고 어셈블리를 반환합니다.
비고
앱에 이미 다른 용도의 AssemblyResolve
처리기가 있는 경우 리소스 확인 코드를 기존 코드와 통합해야 합니다.
Win32 MUI 리소스 로딩
Win32 MUI 리소스 로드는 기본적으로 .NET 위성 어셈블리를 로드하는 것과 동일하지만 대신 C++/CX 또는 C++/WRL 코드를 사용합니다. C++/CX를 사용하면 위의 C# 코드와 밀접하게 일치하는 훨씬 간단한 코드를 작성할 수 있지만, 피하고자 할 수도 있는 C++ 언어 확장, 컴파일러 스위치 및 추가 런타임 오버헤드를 사용합니다. 이 경우 C++/WRL을 사용하면 더 자세한 코드의 비용으로 훨씬 낮은 영향을 주는 솔루션을 제공합니다. 그럼에도 불구하고 ATL 프로그래밍(또는 일반적으로 COM)에 익숙하다면, WRL도 익숙하게 느껴질 것입니다.
다음 샘플 함수는 C++/WRL을 사용하여 특정 리소스 DLL을 로드하고 일반적인 Win32 리소스 API를 사용하여 추가 리소스를 로드하는 데 사용할 수 있는 리소스를 반환 HINSTANCE
하는 방법을 보여 줍니다. .NET 런타임에서 요청한 언어를 사용하여 명시적으로 초기화하는 ResourceContext
C# 샘플과 달리 이 코드는 사용자의 현재 언어를 사용합니다.
#include <roapi.h>
#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
#include <Windows.ApplicationModel.resources.core.h>
#include <Windows.Foundation.h>
#define IF_FAIL_RETURN(hr) if (FAILED((hr))) return hr;
HRESULT GetMrtResourceHandle(LPCWSTR resourceFilePath, HINSTANCE* resourceHandle)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::ApplicationModel::Resources::Core;
using namespace ABI::Windows::Foundation;
*resourceHandle = nullptr;
HRESULT hr{ S_OK };
RoInitializeWrapper roInit{ RO_INIT_SINGLETHREADED };
IF_FAIL_RETURN(roInit);
// Get Windows.ApplicationModel.Resources.Core.ResourceManager statics
ComPtr<IResourceManagerStatics> resourceManagerStatics;
IF_FAIL_RETURN(GetActivationFactory(
HStringReference(
RuntimeClass_Windows_ApplicationModel_Resources_Core_ResourceManager).Get(),
&resourceManagerStatics));
// Get .Current property
ComPtr<IResourceManager> resourceManager;
IF_FAIL_RETURN(resourceManagerStatics->get_Current(&resourceManager));
// get .MainResourceMap property
ComPtr<IResourceMap> resourceMap;
IF_FAIL_RETURN(resourceManager->get_MainResourceMap(&resourceMap));
// Call .GetValue with supplied filename
ComPtr<IResourceCandidate> resourceCandidate;
IF_FAIL_RETURN(resourceMap->GetValue(HStringReference(resourceFilePath).Get(),
&resourceCandidate));
// Get .ValueAsString property
HString resolvedResourceFilePath;
IF_FAIL_RETURN(resourceCandidate->get_ValueAsString(
resolvedResourceFilePath.GetAddressOf()));
// Finally, load the DLL and return the hInst.
*resourceHandle = LoadLibraryEx(resolvedResourceFilePath.GetRawBuffer(nullptr),
nullptr, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
return S_OK;
}
3단계: 리소스 팩 빌드
이제 모든 리소스를 포함하는 "fat pack"이 있으므로 다운로드 및 설치 크기를 최소화하기 위해 별도의 기본 패키지와 리소스 패키지를 빌드하는 두 가지 경로가 있습니다.
- 기존 fat pack을 가져와 번들 생성 도구 을 통해 실행하여 리소스 팩을 자동으로 만듭니다. 이미 fat 팩을 생성하는 빌드 시스템이 있고, 이를 리소스 팩을 생성하기 위해 후처리하려는 경우 이 접근법이 선호됩니다.
- 개별 리소스 패키지를 직접 생성하고 번들로 빌드합니다. 빌드 시스템을 더 많이 제어하고 패키지를 직접 빌드할 수 있는 경우 이 방법을 사용하는 것이 좋습니다.
3.1단계: 번들 만들기
번들 생성기 도구 사용
번들 생성기 도구를 사용하려면 패키지에 대해 만든 PRI 구성 파일을 수동으로 업데이트하여 섹션을 <packaging>
제거해야 합니다.
파일을 수동으로 편집하는 경우 다음 단계를 수행합니다.
올바른 경로, 파일 이름 및 언어를 대체하여 이전과 동일한 방식으로 구성 파일을 만듭니다.
makepri createconfig /cf ..\contoso_demo.xml /dq en-US_de-DE_es-MX /pv 10.0 /o
만든
.xml
파일을 수동으로 열고 전체<packaging&rt;
섹션을 삭제합니다(하지만 다른 모든 항목은 그대로 유지).<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <resources targetOsVersion="10.0.0" majorVersion="1"> <!-- Packaging section has been deleted... --> <index root="\" startIndexAt="\"> <default> ... ...
업데이트된
.pri
구성 파일과 적절한 디렉터리 및.appx
파일 이름을 사용하여 이전과 같이 파일 및 패키지를 빌드합니다(이러한 명령에 대한 자세한 내용은 위 참조).makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /o makeappx pack /m AppXManifest.xml /f ..\resources.map.txt /p ..\contoso_demo.appx /o
패키지를 만든 후 다음 명령을 사용하여 적절한 디렉터리와 파일 이름을 사용하여 번들을 만듭니다.
BundleGenerator.exe -Package ..\contoso_demo.appx -Destination ..\bundle -BundleName contoso_demo
이제 서명하여 최종 단계로 이동할 수 있습니다(아래 참조).
수동으로 리소스 패키지 만들기
리소스 패키지를 수동으로 만들려면 별도의 .pri
및 .appx
파일을 빌드하기 위해 조금 다른 명령 집합을 실행해야 합니다. 이러한 명령은 모두 위에서 사용한 팩 패키지를 만들기 위한 명령과 유사하므로 최소한의 설명만 제공됩니다. 참고: 모든 명령은 현재 디렉터리가 파일이 포함된 AppXManifest.xml
디렉터리라고 가정하지만 모든 파일이 부모 디렉터리에 배치됩니다(필요한 경우 다른 디렉터리를 사용할 수 있지만 이러한 파일로 프로젝트 디렉터리를 오염해서는 안 됨). 언제나처럼 "Contoso" 파일 이름을 사용자 고유의 파일 이름으로 바꿉니다.
다음 명령을 사용하여 기본 언어를 기본 한정자로
구성 파일을 만듭니다. 이 경우 . makepri createconfig /cf ..\contoso_demo.xml /dq en-US /pv 10.0 /o
기본 패키지에 대한 기본
.pri
파일 및.map.txt
파일을 만들고, 프로젝트에 있는 각 언어에 대해 추가 파일 집합을 만들려면 다음 명령을 사용하십시오.makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /o
다음 명령을 사용하여 기본 패키지(실행 코드 및 기본 언어 리소스 포함)를 만듭니다. 평소와 같이, 필요에 따라 이름을 변경하되, 나중에 번들을 더 쉽게 만들 수 있도록 패키지를 별도의 디렉터리에 배치하세요(이 예제에서는
..\bundle
디렉터리를 사용).makeappx pack /m .\AppXManifest.xml /f ..\resources.map.txt /p ..\bundle\contoso_demo.main.appx /o
기본 패키지를 만든 후 각 추가 언어에 대해 다음 명령을 한 번 사용합니다(예: 이전 단계에서 생성된 각 언어 맵 파일에 대해 이 명령을 반복). 다시 말하지만 출력은 별도의 디렉터리(주 패키지와 동일)에 있어야 합니다. 언어는
옵션과 옵션의 및 새 인수(리소스 패키지가 원하는 경우)를 사용하기 지정됩니다. makeappx pack /r /m .\AppXManifest.xml /f ..\resources.language-de.map.txt /p ..\bundle\contoso_demo.de.appx /o
번들 디렉터리의 모든 패키지를 단일
.appxbundle
파일로 결합합니다. 새/d
옵션은 번들에 있는 모든 파일에 사용할 디렉터리를 지정합니다(이전 단계에서 파일이 별도의 디렉터리에 배치되는 이유.appx
).makeappx bundle /d ..\bundle /p ..\contoso_demo.appxbundle /o
패키지를 빌드하는 마지막 단계는 서명입니다.
3.2단계: 번들 서명
파일 .appxbundle
을 번들 생성기 도구를 통해 또는 수동으로 만든 후에는, 기본 패키지와 모든 리소스 패키지가 포함된 단일 파일이 생성됩니다. 마지막 단계는 Windows에서 파일을 설치하도록 파일에 서명하는 것입니다.
signtool sign /fd SHA256 /a /f ..\contoso_demo_key.pfx ..\contoso_demo.appxbundle
그러면 기본 패키지와 모든 언어별 리소스 패키지가 포함된 서명 .appxbundle
된 파일이 생성됩니다. 패키지 파일처럼 두 번 클릭하여 앱을 설치하고 사용자의 Windows 언어 기본 설정에 따라 적절한 언어를 설치할 수 있습니다.