RSS 讀取器教學課程 (具有 VS Code 的 Rust for Windows)
上一個主題介紹了 Rust for Windowst 及 windows crate。
現在,讓我們透過撰寫一個簡單的主控台應用程式來試用 Rust for Windows,該應用程式可從 Really Simple Syndication (RSS) Feed 下載部落格文章的標題。
啟動命令提示字元 (
cmd.exe
),並cd
到您要保留 Rust 專案的資料夾。使用 Cargo,建立一個名為 rss_reader 的新 Rust 專案,並將
cd
到新建立的資料夾:> cargo new rss_reader > Created binary (application) `rss_reader` package > cd rss_reader
然後在 VS Code 中開啟 rss_reader 專案。
code .
讓我們實作主要 rss_reader 專案。 首先,在專案的根目錄開啟
Cargo.toml
檔案。Cargo.toml
檔案是一個描述 Rust 專案的文字檔,包括它擁有的任何相依性。在 windows crate 上新增一個相依性,如下列清單所示。 windows crate 很大。 為了保持建置時間快速,我們只會選取此程式碼所需的
Foundation_Collections
和Web_Syndication
功能。# Cargo.toml ... [dependencies.windows] version = "0.43.0" features = [ "Foundation_Collections", "Web_Syndication", ]
然後,開啟 rss_reader 專案的
src/main.rs
原始程式碼檔案。 在那裡,您將找到 Cargo 預設的 "Hello, world!" 程式碼。 將下列的 use 陳述式新增至main.rs
的開頭:// src\main.rs use windows::{ core::*, Foundation::Uri, Web::Syndication::SyndicationClient }; fn main() { println!("Hello, world!"); }
use 宣告會縮短我們將使用的類型的路徑。 那裡有我們稍早提到的 Uri 類型。
若要建立新的 Uri,請使用下列項目來取代 Cargo 的預設 main 函式:
// src\main.rs ... fn main() -> Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; Ok(()) }
請注意,main 函式的傳回類型是一個 Result 類型 (來自 windows::core:: 模組)。 這將使事情變得更容易,因為處理作業系統 (OS) API 中的錯誤是很常見的。 windows::core::Result 可幫助我們進行錯誤傳播和簡潔的錯誤處理。
您可以在程式碼行結尾看到問號運算子。 為了節省打字時間,我們這樣做是為了使用 Rust 的錯誤傳播和短路邏輯。 這意味著對於這個簡單的例子,我們不必進行大量的手動錯誤處理。 如需此 Rust 功能的詳細資訊,請參閱用於更易於處理錯誤的 ? 運算子。
還要注意來自 windows crate 的 h! 巨集。 我們使用它以從 Rust 字串常值中建構一個 HSTRING 參考。 WinRT API 會廣泛使用 HSTRING 來表示字串值。
為了下載 RSS Feed,我們將建立一個新的 SyndicationClient。
// src\main.rs ... fn main() -> windows::core::Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; let client = SyndicationClient::new()?; Ok(()) }
這個新的函式是一個 Rust 建構函式。 windows crate 中的所有物件都遵循 Rust 慣例,並將其建構函式命名為 new。
現在,我們可以使用 SyndicationClient 來擷取該 Feed。
// src\main.rs ... fn main() -> windows::core::Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; let client = SyndicationClient::new()?; let feed = client.RetrieveFeedAsync(&uri)?.get()?; Ok(()) }
由於 RetrieveFeedAsync 是一個非同步的 API,因此我們會使用阻塞的 get 函式來讓範例保持簡單。 或者,我們也可以在
async
函式內使用await
運算子來合作等待結果。 具有圖形化使用者介面的較複雜應用程式通常會使用async
。現在我們可以逐一查看產生的項目,讓我們只列印出標題。 您也會在下面看到幾行額外的程式碼行,用於設定使用者代理標頭,因為有些 RSS Feed 需要這樣做。
// src\main.rs ... fn main() -> windows::core::Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; let client = SyndicationClient::new()?; client.SetRequestHeader( h!("User-Agent"), h!("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"), )?; let feed = client.RetrieveFeedAsync(&uri)?.get()?; for item in feed.Items()? { println!("{}", item.Title()?.Text()?); } Ok(()) }
現在讓我們確認我們可以藉由按一下 [執行]>[執行但不偵錯] (或按 Ctrl+F5) 來建置並執行。 如果您看到任何未預期的訊息,那麼請確定您已順利完成 Hello, world! 教學課程 (使用 VS Code 來開發 Rust)。
也有 Debug 和 Run 命令內嵌在文字編輯器內。 或者,也可以從
rss_reader
資料夾中的命令提示字元中輸入cargo run
,這會建置並執行程式。在 VS Code 終端機窗格中,您可以看到 Cargo 成功下載並編譯了 windows crate,進而快取結果,並使用它們以在更短的時間內完成後續的組建。 然後,它會建置範例並加以執行,進而顯示部落格文章標題的清單。
這就是編寫 Rust for Windows 的簡單過程。 然而,在幕後,需要大量的精力來建置工具,以便讓 Rust 能夠剖析基於 ECMA-335 (Common Language Infrastructure 或 CLI) 的 .winmd
檔案,同時在執行時忠實地遵循基於 COM 的應用程式二進位介面 (ABI),並兼顧安全性和效率。
顯示訊息方塊
我們確實說過,Rust for Windows 可以讓您呼叫任何 Windows API (過去、現在和未來)。 因此,在本節中,我們將顯示幾個 Windows 訊息方塊。
就像我們對 RSS 專案所做的那樣,在命令提示字元中,
cd
到包含您的 Rust 專案的資料夾。建立一個名為 message_box 的新專案,並在 VS Code 中開啟它:
> cargo new message_box > Created binary (application) `message_box` package > cd message_box > code .
在 VS Code 中,開啟
Cargo.toml
,並新增此專案的 Windows 相依性:# message_box\Cargo.toml ... [dependencies.windows] version = "0.43.0" features = [ "Win32_Foundation", "Win32_UI_WindowsAndMessaging", ]
現在開啟該專案的
src/main.rs
檔案,並新增含新命名空間的use
宣告 (如下所示)。 最後新增程式碼以呼叫 MessageBoxA 和 MessageBoxW 函式。 Windows API 文件主要是以 C/C++ 撰寫的,因此將 API 文件與 windows crate 中的 Rust 投影文件進行比較是很有用的:MessageBoxA (Rust) 和 MessageBoxW (Rust)。// src\main.rs use windows::{ core::*, Win32::UI::WindowsAndMessaging::* }; fn main() { unsafe { MessageBoxA(None, s!("Ansi"), s!("World"), MB_OK); MessageBoxW(None, w!("Wide"), w!("World"), MB_OK); } }
如您所見,我們必須在
unsafe
區塊中使用這些 WIN32 API (請參閱不安全的區塊)。 還要注意 s! 和 w! 巨集,它們可以從 Rust 的 UTF-8 字串常值建立 LPCSTR 和 LPCWSTR 引數,類似我們使用 h! 巨集為 rss_reader 建立 HSTRING 的方式。 Rust 本身是一種原生支援 Unicode 的語言,使用 UTF-8 字串,因此會優先使用廣泛使用 Unicode (帶有 W 尾碼) 的 Windows API,而不是 ANSI (帶有 A 尾碼) 的 API。 如果您在程式碼中使用非英文文字,這一點可能很重要。
這次當您建置並執行時,Rust 會顯示兩個 Windows 訊息方塊。