C#/WinRT

C#/WinRT는 C# 언어에 대한 WinRT(Windows 런타임) 프로젝션 지원을 제공하는 NuGet 패키지 도구 키트입니다. 프로젝션 어셈블리는 대상 언어에 대해 자연스럽고 친숙한 방식으로 WinRT API를 프로그래밍할 수 있는 interop 어셈블리를 나타냅니다. C#/WinRT 프로젝션은 C#과 WinRT 인터페이스 간의 interop 세부 정보를 숨기고, 문자열, URI, 공통 값 형식 및 제네릭 컬렉션과 같은 적절한 .NET 해당 항목에 대한 많은 WinRT 형식의 매핑을 제공합니다.

C#/WinRT는 현재 .NET에서 TFM(대상 프레임워크 모니커)을 사용하여 WinRT API 사용을 지원합니다. 특정 Windows SDK 버전으로 TFM을 설정하면 C#/WinRT에서 생성된 Windows SDK 프로젝션 및 런타임 어셈블리에 대한 참조가 추가됩니다.

C#/WinRT NuGet 패키지를 사용하면 .NET 소비자를 위해 고유한 WinRT interop 어셈블리를 생성하고 참조할 수 있습니다. 최신 C#/WinRT 버전에는 C#의 WinRT 유형 작성 미리 보기도 포함되어 있습니다.

자세한 내용은 C#/WinRT GitHub 리포지토리를 참조하세요.

C#/WinRT에 대한 동기 부여

.NET(이전의 .NET Core)은 디바이스, 클라우드 및 IoT 애플리케이션을 빌드하는 데 사용할 수 있는 오픈 소스 플랫폼 간 런타임입니다.

이전 버전의 .NET Framework 및 .NET Core에는 Windows 고유의 기술인 WinRT에 대한 지식이 기본적으로 제공되었습니다. .NET 6 이상의 이식성 및 효율성 목표를 지원하기 위해 .NET 컴파일러 및 런타임에서 WinRT 프로젝션 지원을 해제하고 C#/WinRT 도구 키트로 이동했습니다(WinRT에 대한 기본 제공 지원이 .NET에서 제거됨 참조). C#/WinRT의 목표는 이전 버전의 C# 컴파일러 및 .NET 런타임에서 제공하는 기본 제공 WinRT 지원을 패리티에 제공하는 것입니다. 자세한 내용은 Windows 런타임 형식의 .NET 매핑을 참조하세요.

C#/WinRT는 WinUI 3을 비롯한 Windows 앱 SDK의 구성 요소도 지원합니다. Windows 앱 SDK는 운영 체제에서 네이티브 Microsoft UI 컨트롤 및 기타 네이티브 구성 요소를 제거합니다. 이를 통해 앱 개발자는 Windows 10 버전 1809 이상 릴리스에서 최신 컨트롤과 구성 요소를 사용할 수 있습니다.

마지막으로 C#/WinRT는 일반적인 도구 키트이며, C# 컴파일러 또는 .NET 런타임에서 WinRT에 대한 기본 제공 지원을 사용할 수 없는 다른 시나리오를 지원하기 위한 것입니다.

새로운 기능

최신 C#/WinRT 릴리스는 Github 리포지토리의 릴리스 정보 페이지에서 찾을 수 있습니다.

사용

C#/WinRT NuGet 패키지는 WinRT 구성 요소에서 C# 프로젝션(interop 어셈블리라고도 함)을 생성하고 C#/WinRT 구성 요소를 작성하는 데 사용할 수 있습니다. C#/WinRT의 사용 시나리오에 대한 자세한 내용은 리포지토리의 사용 가이드를 참조하세요.

interop 어셈블리 생성 및 배포

WinRT API는 WinMD(Windows 메타데이터) 파일에 정의되어 있습니다. C#/WinRT NuGet 패키지(Microsoft.Windows.CsWinRT)에는 WinMD 파일을 처리하고 .NET C# 코드를 생성하는 데 사용할 수 있는 C#/WinRT 컴파일러인 cswinrt.exe가 포함되어 있습니다. C#/WinRT는 C++/WinRT에서 C++ 언어 프로젝션에 대한 헤더를 생성하는 방법과 비슷하게 이러한 원본 파일을 interop 어셈블리로 컴파일합니다. 그런 다음, 일반적으로 NuGet 패키지로 참조할 .NET 애플리케이션용 구현 어셈블리와 함께 C#/WinRT interop 어셈블리를 배포할 수 있습니다.

interop 어셈블리를 생성하고 배포하는 방법에 대한 자세한 내용은 C++/WinRT 구성 요소에서 C# 프로젝션을 생성하고, .NET 앱용 NuGet으로 배포를 참조하세요.

interop 어셈블리 참조

일반적으로 C#/WinRT interop 어셈블리는 애플리케이션 프로젝트에서 참조됩니다. 그러나 중간 interop 어셈블리에서 차례로 참조될 수도 있습니다. 예를 들어 WinUI interop 어셈블리는 Windows SDK interop 어셈블리를 참조합니다.

공식적인 interop 어셈블리를 사용하지 않고 타사 WinRT 구성 요소를 배포하는 경우 애플리케이션 프로젝트에서 interop 어셈블리를 생성하는 절차에 따라 자체의 프라이빗 프로젝션 원본을 생성할 수 있습니다. 이 방법은 프로세스 내에서 동일한 형식의 충돌하는 프로젝션을 생성할 수 있으므로 사용하지 않는 것이 좋습니다. 의미 체계 버전 관리 체계를 따르는 NuGet 패키징은 이를 방지하도록 설계되었습니다. 공식적인 타사 interop 어셈블리가 선호됩니다.

WinRT 형식에 대한 임베디드 지원(미리 보기)

C#/WinRT 버전 1.4.1부터 .NET 및 .NET Standard 2.0 모두에 대한 Windows SDK 프로젝션 및 런타임 원본을 라이브러리 또는 앱의 출력에 포함하기 위한 지원이 포함됩니다. 이는 Windows SDK 형식의 사용이 자체 포함된 경우에 유용합니다. 임베디드 지원은 라이브러리 또는 앱 출력 크기를 줄이는 WinRT.Runtime.dll 및 Microsoft.Windows.SDK.NET.dll에 대한 종속성을 제거합니다. 또한 라이브러리 개발자가 하위 수준 지원을 제공하고 다중 대상 지정의 필요성을 제거할 수 있습니다.

자세한 내용은 리포지토리의 C#/WinRT 포함 설명서를 참조하세요.

WinRT 형식 활성화

C#/WinRT는 Win2D와 같은 타사 구성 요소뿐만 아니라 운영 체제에서 호스팅하는 WinRT 형식도 활성화할 수 있도록 지원합니다. 데스크톱 애플리케이션의 타사 구성 요소 활성화에 대한 지원은 Windows 10 버전 1903 이상에서 사용할 수 있는 등록 무료 WinRT 활성화(Windows 런타임 구성 요소를 사용하여 패키지되지 않은 데스크톱 앱 향상 참조)를 통해 사용하도록 설정됩니다. 네이티브 C++ 구성 요소는 Microsoft.VCLibs.Desktop 이진 파일을 참조하고 사용하는 앱에 전달하기 위해 프로젝트 속성 또는 .vcxproj 파일을 통해 Windows Desktop프로젝트 호환 속성을 True로 설정해야 합니다. 그렇지 않으면 구성 요소가 UWP 앱만 대상으로 하는 경우 앱을 사용하여 VCRT 전달자 패키지가 필요합니다.

C#/WinRT는 위에서 설명한 대로 Windows에서 형식을 활성화하지 못하는 경우에도 활성화 대체 경로를 제공합니다. 이 경우 C#/WinRT는 정규화된 형식 이름에 따라 네이티브 구현 DLL을 찾아서 요소를 점진적으로 제거하려고 시도합니다. 예를 들어 대체 논리는 다음 모듈에서 Contoso.Controls.Widget 형식을 순서대로 활성화하려고 시도합니다.

  1. Contoso.Controls.Widget.dll
  2. Contoso.Controls.dll
  3. Contoso.dll

C#/WinRT는 LoadLibrary 대체 검색 순서를 사용하여 구현 DLL을 찾습니다. 이 대체 동작을 사용하는 앱은 구현 DLL을 앱 모듈과 함께 패키지해야 합니다.

일반 오류 및 문제 해결

  • 오류: "Windows 메타데이터가 제공되거나 검색되지 않았습니다."

    <CsWinRTWindowsMetadata> 프로젝트 속성을 사용하여 Windows 메타데이터를 지정할 수 있습니다. 예를 들면 다음과 같습니다.

    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
    

    C#/WinRT 버전 1.2.1 이상에서 이 속성은 기본적으로 TargetPlatformVersion으로 설정되며, 이 속성은 TargetFramework 속성에 지정된 Windows SDK 버전에서 파생됩니다.

  • 오류 CS0246: 'Windows' 유형 또는 네임스페이스 이름을 찾을 수 없습니다. using 지시문 또는 어셈블리 참조가 누락되었습니까?와 같은 오류가 표시되는 경우

    이 오류를 해결하려면 특정 Windows 버전을 대상으로 하는 <TargetFramework> 속성을 편집합니다. 예를 들면 다음과 같습니다.

    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    

    <TargetFramework> 속성을 지정하는 방법에 대한 자세한 내용은 Windows 런타임 API 호출에 대한 문서를 참조하세요.

  • System.InvalidCastException: ComImport 특성이 있는 인터페이스로 캐스팅하는 경우

    개체를 ComImport 특성이 있는 인터페이스로 캐스팅하는 경우 명시적 캐스트 식을 사용하는 대신 .As<> 연산자를 사용해야 합니다. 예:

    someObject.As<SomeComImportInterface>
    

    자세한 내용은 COM interop 가이드를 참조하세요.

  • System.Runtime.InteropServices.COMException: 클래스가 등록되지 않았습니다(0x80040154 (REGDB_E_CLASSNOTREG)).

    • C++/WinRT 구성 요소에서 C#/WinRT 프로젝션을 사용할 때 이 예외가 표시되면 구성 요소에서 프로젝트 속성 또는 .vcxproj 파일을 통해 Windows Desktop 호환 속성을 True로 설정했는지 확인합니다.

.NET SDK 버전 관리 오류

해당 종속성보다 이전의 .NET SDK 버전으로 빌드된 프로젝트에서 다음 오류 또는 경고가 발생할 수 있습니다.

오류 또는 경고 메시지 이유
경고 MSB3277: 해결할 수 없는 WinRT.Runtime 또는 Microsoft.Windows.SDK.NET의 서로 다른 버전 간의 충돌이 발견되었습니다. 이 빌드 경고는 API 표면에서 Windows SDK 유형을 노출하는 라이브러리를 참조할 때 발생합니다.
오류 CS1705: 어셈블리 'AssemblyName1'은 참조된 어셈블리 'AssemblyName2'보다 높은 버전의 'TypeName'을 사용합니다. 이 빌드 컴파일러 오류는 라이브러리에서 공개된 Windows SDK 유형을 참조하고 사용할 때 발생합니다.
System.IO.FileLoadException 이 런타임 오류는 Windows SDK 유형을 표시하지 않는 라이브러리에서 특정 API를 호출할 때 발생할 수 있습니다.

이러한 오류를 해결하려면 .NET SDK를 최신 버전으로 업데이트합니다. 이렇게 하면 애플리케이션에서 사용하는 런타임 및 Windows SDK 어셈블리 버전이 모든 종속성과 호환됩니다. 이러한 오류는 .NET SDK에 대한 조기 서비스/기능 업데이트 시 발생할 수 있습니다. 런타임 수정 시 어셈블리 버전을 업데이트해야 할 수 있기 때문입니다.

알려진 문제점

알려진 문제 및 주요 변경 내용은 C#/WinRT GitHub 리포지토리에 설명되어 있습니다.

C#/WinRT NuGet 패키지, cswinrt.exe 컴파일러 또는 생성된 프로젝션 원본에서 기능 문제가 발생하는 경우 C#/WinRT 문제 페이지를 통해 문제를 제출하세요.

추가 리소스