RSS 读者教程(适用于 Windows 的 Rust 与 VS Code)
上一主题介绍了 Rust for Windows 与 windows crate。
现在,让我们尝试利用 Rust for Windows 来编写一个简单的控制台应用,从真正简单的整合 (RSS) 源下载博客文章的标题。
在要保存 Rust 项目的文件夹中启动命令提示符 (
cmd.exe
) 和cd
。使用 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 函数的返回类型是来自 windows::core:: 的 Result。 这将使事情变得更容易,因为处理来自操作系统 (OS) API 的错误很常见。 windows::core::Result 可以帮助我们进行错误传播和简洁的错误处理。
你可以在代码行末尾看到问号运算符。 简而言之,我们这样做是为了利用 Rust 的错误传播和短路逻辑。 也就是说,我们不需要对这个简单的示例进行大量的手动错误处理。 若要详细了解 Rust 的这项功能,请参阅利用 ? 运算符简化错误处理。
另请注意 windows crate 中的 h! 宏。 可使用它基于 Rust 字符串文本构造 HSTRING 引用。 WinRT API 对字符串值广泛使用 HSTRING。
为了下载此 RSS 源,我们将创建一个新的 SyndicationClient。
// src\main.rs ... fn main() -> windows::core::Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; let client = SyndicationClient::new()?; Ok(()) }
new 函数是 Rust 构造函数。 windows crate 中的所有对象都遵循 Rust 约定,并将其构造函数命名为 new。
现在,我们可以使用 SyndicationClient 来检索源。
// 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 源需要这样做。
// 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! 教程(Rust 与 VS Code)。
文本编辑器中也嵌入了“调试”和“运行”命令。 或者,在
rss_reader
文件夹中的命令提示符下,键入cargo run
,这将生成并运行程序。在下面的 VS Code“终端”窗格中,可以看到 Cargo 成功地下载并编译了 windows crate,缓存结果,并使用它们在更短时间内完成后续的生成操作。 然后,它生成并运行示例,以显示博客文章标题列表。
这和为 Windows 编写 Rust 程序一样简单。 但实际上,很多开发人员都喜欢生成这个工具,这样 Rust 既可以解析基于 ECMA-335(公共语言基础结构 (CLI))的 .winmd
文件,也可以在运行时如实地使用基于 COM 的应用程序二进制接口 (ABI),同时兼顾安全性和效率。
显示消息框
我们说过,Rust for Windows 可用于调用任何过去、现在和将来的 Windows API。 因此,在本部分中,我们将显示几个 Windows 消息框。
就像我们对 RSS 项目执行的操作一样,应在包含 Rust 项目的文件夹的命令提示符
cd
下进行。创建名为 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 参数;就像我们为 rss_reader 使用 h! 宏创建 HSTRING 一样。 Rust 是带有 UTF-8 字符串的本机 Unicode,因此使用宽 Unicode(W 后缀)Windows API 优于 ANSI(A 后缀)API。 如果在代码中使用非英语文本,应注意这一点。
这次当你生成并运行时,Rust 会显示两个 Windows 消息框。