13
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rust/WinRT] トースト通知を表示する

Last updated at Posted at 2020-05-03

2020年4月30日に, Microsoft から Rust/WinRT のプレビュー版が発表されました!これまでもサードパーティによる winrt クレートはありましたが, 今後は Microsoft が WinRT の Rust 言語プロジェクションをサポートしていくことになります (issue76).

興味があったので早速試してみました. お題はトースト通知を表示することです (参考資料が豊富にありとっつきやすかったので).

2020-06-09追記 crates.io に winrt 0.7.0 が公開されたのに伴いコード修正.

2021-03-20追記 Rust for Windows (windows-rs) に改名されたのに伴いコード修正. Win10 v20H2, windows="0.5.0" で動作確認しました.

環境

本記事では Rust/WinRT の動作確認に Win10 Pro v1909 build 18363.778 を用いました.

  • Visual Studio Build Tools 2019 (16.5.4)
  • Rust 1.43.0 stable-x86_64-pc-windows-msvc

これだけで動きました. あたかも WinRT が pure Rust クレートかのような簡単さです. ただコンパイルが毎回5秒程度かかるのが若干気になります. あとドキュメントがまだオンラインで見られないため, cargo doc して自分で生成する必要があります.

2021-03-20追記 このあたりの問題は解決しましたが説明すると長くなるのでいつか別記事にします. さしあたりチュートリアルを読むことを強くお勧めします.

コード

参考文献の最初に挙げた C++/WinRT のコードを翻訳しただけですが, いろいろと苦労しました.

build.rs
fn main() {
    windows::build!(
        windows::ui::*,
        windows::data::xml::dom::{XmlDocument, XmlText, XmlNodeList},
        windows::ui::notifications::*,
    );
}
src/main.rs
mod bindings {
    ::windows::include_bindings!();
}

use bindings::windows::ui::notifications::{
    ToastNotificationManager, ToastTemplateType, ToastNotification,
};

fn main() -> windows::Result<()> {
    let notification_manager = ToastNotificationManager::get_default()?;

    let toast_xml = ToastNotificationManager::get_template_content(ToastTemplateType::ToastText01)?;

    // 通知の内容を設定する
    let text_node = toast_xml.get_elements_by_tag_name("text")?.item(0)?;
    let text = toast_xml.create_text_node(r"Hello from Rust/WinRT!")?;
    text_node.append_child(text)?;

    // トースト通知を表示する.
    // v1709 以降は AppId が必要なので, Powershell のものを使う
    let toast = ToastNotification::create_toast_notification(toast_xml)?;
    notification_manager
        .create_toast_notifier_with_id("{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\\WindowsPowerShell\\v1.0\\powershell.exe")?
        .show(toast)?;

    std::thread::sleep(std::time::Duration::from_millis(10)); // <- この行を消すとなぜかトースト通知が表示されない
    Ok(())
}

よくわからなかった点

  • シングルバイナリでは AppId を発行することができない?
  • 参考文献その1では ExpirationTime をセットしているが, windows::foundation::DateTime 型の取得まわりがうまくいかなかった.
  • 最後にスリープさせないと通知が出ずにプログラムが終了してしまう.

参考文献

13
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?