다음을 통해 공유


UI 및 해당 앱 패키지 매니페스트의 문자열 지역화

Windows App SDK 앱의 현지화 가치 제안에 대한 자세한 내용은 글로벌화 및 현지화를 참조하십시오.

앱에서 다른 표시 언어를 지원하도록 하고 코드, XAML 태그 또는 앱 패키지 매니페스트에 문자열 리터럴이 있으면 해당 문자열을 리소스 파일(.resw)로 이동합니다. 그러면 앱에서 지원하는 언어별로 해당 리소스 파일의 변환된 복사본을 만들 수 있습니다.

하드 코드된 문자열 리터럴은 명령적 코드 또는 XAML 태그, 예를 들어 TextBlockText 속성으로 표시될 수 있습니다. 앱 패키지 매니페스트 원본 파일(Package.appxmanifest파일)에 표시될 수도 있습니다. 예를 들면 Visual Studio 매니페스트 디자이너의 애플리케이션 탭에 표시 이름에 대한 값으로 표시됩니다. 이러한 문자열을 리소스 파일(.resw)로 이동하고 앱 및 매니페스트에 하드 코드된 문자열 리터럴을 리소스 식별자에 대한 참조로 바꿉니다.

이미지 리소스 파일에 하나의 이미지 리소스만 있는 이미지 리소스와는 달리 여러 문자열 리소스는 문자열 리소스 파일에 포함되어 있습니다. 문자열 리소스 파일은 리소스 파일(.resw)이며 일반적으로 이 유형의 리소스 파일을 프로젝트의 \Strings 폴더에 만듭니다. 리소스 파일(.resw) 이름에 한정자를 사용하는 방법에 대한 배경 지식은 언어, 규모 및 기타 한정자에 맞게 리소스 조정을 참조하세요.

리소스 파일에 문자열 저장

  1. 앱의 기본 언어를 설정합니다.

    1. Visual Studio에서 솔루션을 연 상태로 Package.appxmanifest를 엽니다.
    2. 애플리케이션 탭에서 기본 언어가 제대로 설정되어 있는지 확인합니다(예: "en" 또는 "en-US"). 나머지 단계에서는 기본 언어를 "en-US"로 설정했다고 가정합니다.

    참고 항목

    최소한 이 기본 언어에 맞게 지역화된 문자열 리소스를 제공해야 합니다. 이러한 리소스는 사용자의 기본 설정 언어 또는 표시 언어 설정에 대해 더 나은 일치를 찾을 수 없는 경우 로드됩니다.

  2. 기본 언어에 대한 리소스 파일(.resw)을 만듭니다.

    1. 프로젝트 노드에서 새 폴더를 만들고 이름을 Strings로 지정합니다.
    2. Strings 아래에서 새 하위 폴더를 만들고 이름을 en-US로 지정합니다.
    3. en-US 아래에서 새 리소스 파일(.resw)( 새 항목 추가 대화 상자의 WinUI 파일 형식 아래)을 만들고 이름이 Resources.resw로 지정되어 있는지 확인합니다.

    참고 항목

    이식하려는 .NET 리소스 파일(.resx)이 있는 경우 XAML 및 UI 이식을 참조하세요.

  3. Resources.resw를 열고 이러한 문자열 리소스를 추가합니다.

    Strings/en-US/Resources.resw

    Strings E N U Resources.resw > > 파일의 리소스 추가 테이블 스크린샷

    이 예에서 "Greeting"은 태그에서 참조할 수 있는 문자열 리소스 식별자이며, 이에 대해 알아보겠습니다. Greeting" 식별자의 경우 문자열은 Text 속성에 대해 제공되고 문자열은 Width 속성에 대해 제공됩니다. "Greeting.Text"는 UI 요소의 속성에 해당하므로 속성 식별자의 예가 됩니다. 또한 예를 들어 이름 열에 "Greeting.Foreground"를 추가하고 값을 "빨간색"으로 설정수 있습니다. "Farewell" 식별자는 단순한 문자열 리소스 식별자입니다. 하위 속성을 가지지 않으며 명령적 코드에서 로드됩니다. 이에 대해 설명할 것입니다. 설명 열은 번역가에게 특별한 지침을 전달하기 좋은 위치입니다.

    이 예에서 "Farewell"이라는 단순한 문자열 리소스 식별자 항목이 있기 때문에 동일한 식별자에 기반한 속성 식별자 또한 가질 수 없습니다. 따라서 "Farewell.Text"를 추가하면 Resources.resw를 빌드할 때 중복된 항목 오류가 발생합니다.

    리소스 식별자는 대/소문자를 구분하지 않으며 리소스 파일별로 고유해야 합니다. 의미 있는 리소스 식별자를 사용하여 번역가를 위한 추가 컨텍스트를 제공해야 합니다. 그리고 문자열 리소스를 번역에 사용하도록 보낸 이후에는 리소스 식별자를 변경하지 마세요. 지역화 팀은 리소스 식별자를 사용하여 리소스의 추가, 삭제 및 업데이트를 추적합니다. 리소스 식별자를 변경하면("리소스 식별자 전환"이라고도 함) 문자열을 삭제하고 다른 문자열을 추가한 것처럼 보이므로 문자열을 다시 번역해야 합니다.

XAML의 문자열 리소스 식별자 참조

x:Uid 지시어를 사용하여 태그의 컨트롤 또는 기타 요소를 문자열 리소스 식별자와 연결할 수 있습니다.

<TextBlock x:Uid="Greeting"/>

실행 시 \Strings\en-US\Resources.resw가 로드됩니다(현재 이것이 프로젝트의 유일한 리소스 파일입니다). TextBlockx:Uid 지시어로 조회를 실행하여 문자열 리소스 식별자 "Greeting"을 포함하는 Resources.resw 내에 있는 속성 식별자를 찾을 수 있습니다. "Greeting.Text" 및 "Greeting.Width" 속성 식별자가 검색되고 해당 값은 TextBlock에 적용되며 태그에 로컬로 설정된 모든 값을 재정의합니다. "Greeting.Foreground" 값 또한 사용자가 추가한 경우 적용됩니다. 그러나 유일한 속성 식별자는 XAML 태그 요소의 속성을 설정하는 데 사용되기 때문에 이 TextBlock에서 x:Uid를 "Farewell"로 설정해도 영양을 미치지 않습니다. Resources.resw 문자열 리소스 식별자 "Farewell"을 포함하지만 속성 식별자는 포함하지 않습니다.

XAML 요소에 문자열 리소스 식별자를 할당할 해당 식별자에 대한 모든이 XAML 요소에 적절한지 확인하세요. 예를 들어 TextBlock에서 x:Uid="Greeting"을 설정하면 TextBlock 유형에 Text 속성이 있기 때문에 "Greeting.Text"가 확인됩니다. 그러나 Buttonx:Uid="Greeting"을 설정하는 경우 Button 형식의 텍스트 속성이 없기 때문에 "Greeting.Text"는 런타임 오류를 발생합니다. 이 경우에 대한 한 가지 해결 방법은 "ButtonGreeting.Content"라는 속성 식별자를 작성하고 Buttonx:Uid="ButtonGreeting"을 설정하는 것입니다.

리소스 파일에서 너비를 설정하는 대신 콘텐츠에 동적으로 크기를 맞추는 컨트롤을 허용하도록 할 수 있습니다.

참고 항목

연결된 속성의 경우 .resw 파일의 Name 열에 특수 구문이 필요합니다. 예를 들어 "Greeting" 식별자에 대한 AutomationProperties.Name 연결된 속성에 대한 값을 설정하려면 이름 열에서 이를 입력합니다.

Greeting.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name

코드에서 문자열 리소스 식별자 참조

명시적으로 단순한 문자열 리소스 식별자를 기반으로 문자열 리소스를 로드할 수 있습니다.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader();
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("Farewell");

클래스 라이브러리 프로젝트 내에서 이 동일한 코드를 사용할 수 있습니다. 런타임 시 라이브러리를 호스팅하는 앱의 리소스가 로드됩니다. 앱에는 뛰어난 지역화 수준이 있을 가능성이 높으므로 라이브러리를 호스팅하는 앱에서 리소스를 로드하는 것이 좋습니다. 라이브러리는 리소스를 제공한 다음 호스팅 앱에 이러한 리소스를 입력으로 교체하는 옵션을 제공해야 합니다.

리소스 이름이 분할된 경우("." 문자 포함) 리소스 이름에서 점을 슬래시("/") 문자로 바꿉니다. 예를 들어 속성 식별자에는 점이 포함됩니다. 따라서 코드에서 그 중 하나를로드하기 위해이 대체를 수행해야합니다.

this.myXAMLTextBlockElement.Text = resourceLoader.GetString("Fare/Well"); // <data name="Fare.Well" ...> ...

확실하지 않은 경우 MakePri.exe를 사용하여 앱의 PRI 파일을 덤프할 수 있습니다. 각 리소스의 uri은 덤프된 파일에 표시됩니다.

<ResourceMapSubtree name="Fare"><NamedResource name="Well" uri="ms-resource://<GUID>/Resources/Fare/Well">...

앱 패키지 매니페스트에서 문자열 리소스 식별자 참조

  1. 기본적으로 앱의 Display name가 문자열 리터럴로 표현되는 앱 패키지 매니페스트 원본 파일(Package.appxmanifest 파일)을 엽니다.

    표시 이름이 Adventure Works Cycles로 설정된 애플리케이션 탭을 보여 주는 Package.appxmanifest 파일의 스크린샷.

  2. 이 문자열의 지역화된 버전을 만들려면 Resources.resw를 열고 이름이 "AppDisplayName"이고 값이 "Adventure Works Cycles"인 새 문자열 리소스를 추가합니다.

  3. 표시 이름 문자열 리터럴을 방금 만든 문자열 리소스 식별자 ("AppDisplayName")에 대한 참조로 바꿉니다. ms-resourceURI(Uniform Resource Identifier) 스키마를 사용하여 이 작업을 수행합니다.

    표시 이름이 M S 리소스 앱 표시 이름으로 설정된 애플리케이션 탭을 보여 주는 Package.appxmanifest 파일의 스크린샷.

  4. 지역화하고자 하는 매니페스트의 각 문자열에 대해 이 프로세스를 반복합니다. 예를 들면 앱의 짧은 이름(시작의 앱 타일에 표시되도록 구성할 수 있음)입니다. 지역화할 수 있는 앱 패키지 매니페스트의 모든 항목 목록을 보려면 지역화할 수 있는 매니페스트 항목을 참조하세요.

문자열 리소스 지역화

  1. 다른 언어에 대한 리소스 파일(.resw)의 복사본을 만듭니다.

    1. "Strings" 아래에서 새 하위 폴더를 만들고 독일어(독일)에 대해 이름을 "de-DE"로 지정합니다.

    참고 항목

    참고 폴더 이름에 모든 BCP-47 언어 태그를 사용할 수 있습니다. 언어 한정자 및 일반 언어 태그 목록에 대한 자세한 내용은 언어, 규모 및 기타 한정자에 맞게 리소스 조정을 참조하세요. 2. Strings/de-DE 폴더에 Strings/en-US/Resources.resw 의 복사본을 만듭니다.

  2. 문자열을 번역합니다.

    1. Strings/de-DE/Resources.resw를 열고 값 열에서 값을 번역합니다. 설명을 번역할 필요가 없습니다.

    Strings/de-DE/Resources.resw

    리소스 추가, 독일어

원하는 경우 추가 언어에 대해 1단계와 2단계를 반복합니다.

Strings/fr-FR/Resources.resw

리소스 추가, 프랑스어

앱 테스트

앱에서 기본 표시 언어를 테스트합니다. 그런 다음 설정>시간 & 언어>지역 & 언어>언어에서 표시 언어를 변경하고 앱을 다시 테스트할 수 있습니다. UI와 셸의 문자열을 확인합니다(예: 제목 표시줄인 표시 이름과 타일의 짧은 이름).

참고 항목

표시 언어 설정과 일치하는 폴더 이름을 찾을 수 있을 경우 해당 폴더 내의 리소스 파일이 로드됩니다. 그렇지 않은 경우 앱의 기본 언어에 대한 리소스로 대체됩니다.

여러 개의 리소스 파일로 문자열 팩터링

모든 문자열을 단일 리소스 파일(resw)에 두거나 여러 리소스 파일에 팩터링할 수 있습니다. 예를 들어 하나의 리소스 파일에 오류 메시지를 두고 앱 패키지 매니페스트 문자열은 다른 파일에, UI 문자열은 세 번째 파일에 두고자 할 수 있습니다. 이 경우 폴더 구조는 이러한 모습입니다.

독일어, 미국 영어 및 프랑스어 로캘 폴더와 파일이 있는 Adventure Works Cycles > Strings 폴더를 보여 주는 솔루션 패널의 스크린샷

특정 파일에 대한 문자열 리소스 식별자 참조 범위를 지정하려면 식별자 전에 /<resources-file-name>/을 추가하면 됩니다. 아래의 태그 예는 ErrorMessages.resw가 이름이 "PasswordTooWeak.Text"고 값이 오류를 설명하는 리소스를 포함한다고 가정합니다.

<TextBlock x:Uid="/ErrorMessages/PasswordTooWeak"/>

리소스 파일의 문자열 리소스 식별자 앞에 추가 /<resources-file-name>/ 하기만 하면 됩니다Resources.resw. 이는 "Resources.resw"가 기본 파일 이름이므로 파일 이름을 생략한 경우 이것이 파일 이름으로 간주됩니다(이 항목의 이전 예에서 설명).

아래의 코드 예는 ErrorMessages.resw가 이름이 "MismatchedPasswords"고 값이 오류를 설명하는 리소스를 포함한다고 가정합니다.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("ErrorMessages");
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("MismatchedPasswords");

"AppDisplayName" 리소스를 Resources.resw에서 ManifestResources.resw로 이동하고자 하는 경우 앱 패키지 매니페스트에서 ms-resource:AppDisplayNamems-resource:/ManifestResources/AppDisplayName으로 변경합니다.

리소스 파일 이름이 분할된 경우("." 문자 포함) 참조할 때 이름에 점을 그대로 둡니다. 리소스 이름과 같이 점을 슬래시("/") 문자로 바꾸지 마세요.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("Err.Msgs");

확실하지 않은 경우 MakePri.exe를 사용하여 앱의 PRI 파일을 덤프할 수 있습니다. 각 리소스의 uri은 덤프된 파일에 표시됩니다.

<ResourceMapSubtree name="Err.Msgs"><NamedResource name="MismatchedPasswords" uri="ms-resource://<GUID>/Err.Msgs/MismatchedPasswords">...

특정 언어 또는 다른 컨텍스트에 대한 문자열 로드

기본 ResourceContext ( ResourceLoader를생성할 때 획득)에는 각 한정자 이름에 대한 한정자 값이 포함되어 있으며, 이는 기본 런타임 컨텍스트(즉, 현재 사용자 및 시스템에 대한 설정)를 나타냅니다. 리소스 파일(.resw)은 이름의 한정자를 기반으로 해당 런타임 컨텍스트의 한정자 값과 일치합니다.

하지만 앱에서 시스템 설정을 재정의하여 로드할 일치하는 리소스 파일을 찾을 때 사용할 언어, 배율, 또는 기타 한정자 값을 명시하고자 할 수 있습니다. 예를 들어, 사용자가 도구 설명 또는 오류 메시지에 대해 다른 언어를 선택할 수 있도록 할 수 있습니다.

이는 새 ResourceContext를, 구성하고 해당 값을 재정의한 다음 문자열 조회에서 해당 컨텍스트 개체를 사용하여 수행할 수 있습니다.

var resourceManager = new Microsoft.Windows.ApplicationModel.Resources.ResourceManager();
var resourceContext = resourceManager.CreateResourceContext();
resourceContext.QualifierValues["Language"] = "de-DE";
var resourceMap = resourceManager.MainResourceMap.GetSubtree("Resources");
this.myXAMLTextBlockElement.Text = resourceMap.GetValue("Farewell", resourceContext).ValueAsString;

위 예에서와 같이 QualifierValues는 모든 한정자에 대해 사용할 수 있습니다. 특수한 언어의 경우 대신 이를 수행할 수 있습니다.

resourceContext.Languages = new string[] { "de-DE" };

클래스 라이브러리에서 문자열 로드

참조된 클래스 라이브러리의 문자열 리소스는 일반적으로 빌드 프로세스 중에 포함된 패키지의 하위 폴더에 추가됩니다. 이러한 문자열의 리소스 식별자는 대개 LibraryName/ResourcesFileName/ResourceIdentifier의 형식을 띱니다.

라이브러리는 자체 리소스에 대한 ResourceLoader를 가져올 수 있습니다. 예를 들어 다음 코드는 라이브러리 또는 이를 참조하는 앱이 라이브러리의 문자열 리소스에 대한 ResourceLoader를 가져오는 방법을 보여줍니다.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("ContosoControl/Resources");
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("exampleResourceName");

경로가 의심되는 경우 구성 요소 또는 라이브러리의 PRI 파일을 덤프하도록 MakePri.exe 명령줄 옵션를 지정할 수 있습니다. 각 리소스의 uri은 덤프된 파일에 표시됩니다.

<NamedResource name="exampleResourceName" uri="ms-resource://Contoso.Control/Contoso.Control/ReswFileName/exampleResourceName">...

다른 패키지에서 문자열 로드

앱 패키지에 대한 리소스는 현재 ResourceManager에서 액세스할 수 있는 패키지의 자체 최상위 ResourceMap을 통해 관리 및 액세스할 수 있습니다. 각 패키지 내에 다양한 구성 요소는 자체 ResourceMap 하위 트리를 가지며 ResourceMap.GetSubtree를 통해 액세스할 수 있습니다.

프레임워크 패키지는 절대 리소스 식별자 URI로 자체 리소스에 액세스할 수 있습니다. 자세한 내용은 UWP 설명서의 URI 체계도 참조하세요.

패키지되지 않은 애플리케이션에서 문자열 로드

Windows 버전 1903(2019년 5월 업데이트)을 기준으로 패키지되지 않은 애플리케이션도 리소스 관리 시스템을 활용할 수 있습니다.

Windows App SDK 사용자 컨트롤/라이브러리를 만들고 문자열을 리소스 파일에 저장하기만 하면 됩니다. 그런 다음 XAML에서 문자열 리소스 식별자를 참조하거나, 코드에서 문자열 리소스 식별자를 참조하거나, 클래스 라이브러리에서 문자열을 로드할 수 있습니다.

패키지되지 않은 애플리케이션에서 리소스를 사용하려면 다음과 같은 몇 가지 작업을 수행해야 합니다.

  1. 패키지되지 않은 시나리오에서 기본 보기가 없도록 코드에서 리소스를 확인할 때 ResourceManager의 오버로드된 생성자를 사용하여 앱의 .pri 파일의 파일 이름을 전달합니다.
  2. MakePri.exe를 사용하여 앱의 resources.pri 파일을 수동으로 생성합니다.
    • makepri new /pr <PROJECTROOT> /cf <PRICONFIG> /of resources.pri을 실행합니다.
    • <PRICONFIG>는 "<packaging>" 섹션을 생략해야 모든 리소스가 단일 resources.pri 파일에 번들됩니다. createconfig에서 만든 기본 MakePri.exe 구성 파일을 사용하는 경우 "<packaging>" 섹션을 만든 후 수동으로 삭제해야 합니다.
    • <PRICONFIG>는 프로젝트의 모든 리소스를 단일 resources.pri 파일로 병합하는 데 필요한 모든 관련 인덱서를 포함해야 합니다. createconfig에 의해 만들어진 기본 MakePri.exe 구성 파일에는 모든 인덱서가 포함됩니다.
    • 기본 구성을 사용하지 않는 경우 프로젝트 루트 내에 있는 프로젝트 참조, NuGet 참조 등에서 찾은 PRI를 병합하려면 PRI 인덱서가 활성화되어 있는지 확인합니다(이 작업을 수행하는 방법에 대한 기본 구성 검토).

      참고 항목

      /IndexName을 생략하고 프로젝트에 앱 매니페스트가 없으면 PRI 파일의 IndexName/root 네임스페이스가 자동으로 애플리케이션으로 설정되며, 런타임은 패키지되지 않은 앱에 대해 이를 인식합니다(이렇게 하면 패키지 ID에 대한 이전의 하드 종속성이 제거됨). 리소스 URI를 지정할 때 루트 네임스페이스를 생략하는 ms-resource:/// 참조는 애플리케이션을 패키지되지 않은 앱의 루트 네임스페이스로 유추합니다(또는 ms-resource://Application/에서와 같이 애플리케이션을 명시적으로 지정할 수 있음).

  3. PRI 파일을 .exe의 빌드 출력 디렉터리에 복사합니다.
  4. .exe를 실행

    참고 항목

    리소스 관리 시스템은 패키지되지 않은 앱의 언어를 기반으로 리소스를 확인할 때 사용자 기본 설정 언어 목록 대신 시스템 표시 언어를 사용합니다. 사용자 기본 설정 언어 목록은 Windows 앱 SDK 패키지 앱에만 사용됩니다.

Important

리소스가 수정될 때마다 PRI 파일을 수동으로 다시 작성해야 합니다. MakePri.exe 명령을 처리하고 resources.pri 출력을 .exe 디렉터리에 복사하는 빌드 후 스크립트를 사용하는 것이 좋습니다.

중요 API

참고 항목