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 類型:
- Contoso.Controls.Widget.dll
- Contoso.Controls.dll
- 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。
- 如果您在從 C++/WinRT 元件取用 C#/WinRT 投影時看到這個例外狀況,請確定元件已透過專案屬性或透過
.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 問題頁面,將問題提交給我們。