Share via


C#/WinRT

C#/WinRT 是 NuGet 封裝的工具組,其針對 C# 語言提供 Windows 執行階段 (WinRT) 投影支援。 投影組件是 Interop 組件,可讓 WinRT API 以自然且熟悉的方式進行目標語言的程式設計。 C#/WinRT 投影會隱藏 C# 和 WinRT 介面之間的 Interop 詳細資料,並將許多 WinRT 類型對應提供給適當的 .NET 對等項目,例如字串、URI、通用值類型和泛型集合。

C#/WinRT 目前透過在 .NET 中使用 目標 Framework Monikers (TFMs) 來提供取用 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 也支援 Windows App SDK 中的元件,包括 WinUI 3。 Windows App SDK 會將原生 Microsoft UI 控制項和其他原生元件從作業系統中取出。 這可讓應用程式開發人員使用 Windows 10 1809 版和更新版本上的最新控制項和視覺效果。

最後,C# /WinRT 是一般的工具組,目的是為了支援無法在 C# 編譯器或 .NET 執行階段中使用內建 WinRT 支援的其他案例。

新功能

您可以在 Github 存放庫中的 版本資訊 頁面上找到最新的 C#/WinRT 版本。

使用方式

C#/WinRT NuGet 套件可用來從 WinRT 元件和 Authoring C#/WinRT 元件中產生 C# 投影 (也稱為 Interop 組件)。 如需 C#/WinRT 使用案例的詳細資訊,請參閱存放庫上的 使用指南

產生並散發 Interop 組件

WinRT API 會在 Windows 中繼資料 (WinMD) 檔案中定義。 C#/WinRT NuGet 套件 (Microsoft.Windows.CsWinRT) 包含 C# /WinRT 編譯器 (cswinrt.exe),可用來處理 WinMD 檔案並產生 .NET C# 程式碼。 C#/WinRT 會將這些來源檔案編譯成 Interop 組件,類似於 C++/WinRT 產生 C++ 語言投影標頭的方式。 接著,您可以散發 C#/WinRT Interop 組件以及 .NET 應用程式的實作組件到傳址,通常以 NuGet 套件的形式。

如需如何產生及散發 Interop 組件的詳細資訊,請參閱 從 C++/WinRT 元件產生 C# 投影,作爲 .NET 應用程式的 NuGet 散發

參考 interop 組件

通常,C#/WinRT interop 組件會由應用程式專案來參考。 但是,也可以讓中繼 interop 組件來輪流參考。 例如,WinUI interop 組件會參考 Windows SDK interop 組件。

如果您散發第三方 WinRT 元件,但沒有官方 Interop 組件,應用程式專案可能會遵循建立 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 支援啟用作業系統所裝載的 WinRT 類型,以及 Win2D 之類的第三方元件。 已啟用桌面應用程式中的第三方元件的支援,可透過 Windows 10 1903 版和更新版本中的註冊免費 WinRT 來加以啟用 (請參閱 使用 Windows 執行階段元件增強非封裝桌面應用程式)。 原生 C++ 元件應該透過專案屬性或 .vcxproj 檔案將 Windows Desktop Compatible 屬性設定為 True ,以便參考並轉送 Microsoft.VCLibs.Desktop 二進位檔來取用應用程式。 否則,如果元件僅以 UWP 應用程式為目標,則取用應用程式需要 VCRT 轉寄站 套件。

如果 Windows 無法啟用上述類型,則 C#/WinRT 也會提供啟用後援方法。 在此情況下,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 指示詞或組件參考?)

    若要解決此錯誤,請編輯 <TargetFramework> 屬性,以特定的 Windows 版本為目標,例如:

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

    如需指定 <TargetFramework> 屬性的詳細資訊,請參閱呼叫 Windows 執行階段 API 上的文件。

  • 當轉換成具有 ComImport 屬性的介面時,System.InvalidCastException

    將物件轉換成具有 ComImport 屬性的介面時,您必須使用 .As<> 運算子,而不要使用明確的 轉換運算式。 例如:

    someObject.As<SomeComImportInterface>
    

    如需詳細資訊,請參閱 COM Interop 指南

  • System.Runtime.InteropServices.COMException: 類別未註冊 (0x80040154 (REGDB_E_CLASSNOTREG))

    • 如果您在從 C++/WinRT 元件取用 C#/WinRT 投影時看到這個例外狀況,請確定元件已透過專案屬性或透過 .vcxproj 檔案將 Windows Desktop Compatible 屬性設定為 True

.NET SDK 版本設定錯誤

在以比其任何相依性還舊的 .NET SDK 版本所建置的專案中,您可能會遇到下列錯誤或警告。

錯誤或警告訊息 原因
警告 MSB3277: 無法解析在不同的 WinRT.Runtime 或 Microsoft.Windows.SDK.NET 版本之間發現的衝突。 如果參考的程式庫在其 API 介面上公開 Windows SDK 類型,就會發生此組建警告。
錯誤 CS1705: 組件 'AssemblyName1' 使用的 'TypeName' 高於所參考的組件 'AssemblyName2' 的版本 如果參考並取用程式庫中公開的 Windows SDK 類型,就會發生此組建編譯器錯誤。
System.IO.FileLoadException 在未公開 Windows SDK 類型的程式庫中呼叫 API 時,可能會發生此執行階段錯誤。

若要修正這些錯誤,請將您的 .NET SDK 更新為最新版本。 這麼做可確保應用程式所使用的執行階段和 Windows SDK 組件版本會與所有相依性相容。 .NET SDK 的早期服務/功能更新可能會發生這些錯誤,因為執行階段修正可能需要更新組件版本。

已知問題

已知問題和重大變更會在 C#/WinRT GitHub 存放庫中註明。

如果您在 C# /WinRT NuGet 套件、cswinrt.exe 編譯器或產生的投影來源上遇到任何功能問題,請透過 C#/WinRT 問題頁面,將問題提交給我們。

其他資源