Udostępnij za pośrednictwem


Samouczek czytnika RSS (Rust dla systemu Windows z programem VS Code)

W poprzednim temacie przedstawiono Rust dla systemu Windows i skrzynię okien.

Teraz wypróbujmy rust dla systemu Windows, pisząc prostą aplikację konsolową, która pobiera tytuły wpisów w blogu z kanału informacyjnego Rss (Really Simple Syndication).

  1. Uruchom wiersz polecenia (cmd.exe), a następnie cd do folderu, w którym chcesz przechowywać swoje projekty w Rust.

  2. Za pomocą narzędzia Cargo utwórz nowy projekt Rust o nazwie rss_readeri cd do nowo utworzonego folderu:

    > cargo new rss_reader
    >     Created binary (application) `rss_reader` package
    > cd rss_reader
    
  3. Następnie otwórz projekt rss_reader w programie VS Code.

    code .
    
  4. Rusznijmy do realizacji głównego projektu rss_reader. Najpierw otwórz Cargo.toml plik w katalogu głównym projektu. Cargo.toml Plik to plik tekstowy opisujący projekt Rust, w tym wszelkie zależności, które ma.

    Dodaj zależność na pakiet windows , jak pokazano w poniższym wykazie. okna skrzynia jest duża. Aby zapewnić szybkie czasy kompilacji, wybierzemy tylko potrzebne dla tego kodu funkcje Foundation_Collections i Web_Syndication.

    # Cargo.toml
    ...
    
    [dependencies.windows] 
    version = "0.43.0"
    features = [
        "Foundation_Collections",
        "Web_Syndication",
    ]
    
  5. Następnie otwórz plik kodu źródłowego projektu src/main.rs. Tam znajdziesz domyślny kod Cargo "Hello, world!". Dodaj następującą instrukcję użyj instrukcji na początku main.rs:

    // src\main.rs
    use windows::{
        core::*,
        Foundation::Uri,
        Web::Syndication::SyndicationClient
    };
    
    fn main() {
        println!("Hello, world!");
    }
    

    Deklaracja użycia skraca ścieżkę do typów, które będziemy używać. Istnieje typ identyfikatora URI, o którym wspomniano wcześniej.

  6. Aby utworzyć nowy identyfikator Uri , zastąp domyślną funkcję main ładunku następującą:

    // src\main.rs
    ...
    
    fn main() -> Result<()> {
        let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?;
    
        Ok(())
    }
    

    Zauważ, że typ zwracany głównej funkcji to Resultz windows::core::. To ułatwi zadanie, jako że często mamy do czynienia z błędami pochodzącymi z interfejsów API systemu operacyjnego (OS). windows::core::Result pomaga nam w propagacji błędów i zwięzłej obsłudze błędów.

    Operator znaku zapytania można zobaczyć na końcu wiersza kodu. Aby zaoszczędzić na wpisywaniu, robimy to w celu użycia logiki propagacji błędów i zwarć Rusta. Oznacza to, że w tym prostym przykładzie nie musimy wykonywać ręcznej obsługi błędów. Aby uzyskać więcej informacji na temat tej funkcji Rust, zobacz Operator ? dla łatwiejszej obsługi błędów.

    Zwróć również uwagę na makro h! z modułu windows. Używamy tego do konstruowania odwołania HSTRING z literału ciągu Rust. API WinRT szeroko używa HSTRING do wartości tekstowych.

  7. Aby pobrać kanał informacyjny RSS, utworzymy nowy SyndicationClient.

    // src\main.rs
    ...
    
    fn main() -> windows::core::Result<()> {
        let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?;
        let client = SyndicationClient::new()?;
    
        Ok(())
    }
    

    Nowa funkcja jest konstruktorem Rust. Wszystkie obiekty w skrzynce windows są zgodne z konwencją Rust i nazywają swoje konstruktory new.

  8. Teraz możemy użyć SyndicationClient, aby pobrać kanał informacyjny.

    // 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(())
    }
    

    Ponieważ RetrieveFeedAsync jest asynchronicznym interfejsem API, używamy funkcji blokującej get, aby przykład pozostał prosty. Alternatywnie możemy użyć await operatora w async funkcji, aby wspólnie oczekiwać na wyniki. Bardziej złożona aplikacja z graficznym interfejsem użytkownika często używa metody async.

  9. Teraz możemy iterować elementy wynikowe i wyświetlić tylko tytuły. Zobaczysz również kilka dodatkowych wierszy kodu poniżej, żeby ustawić nagłówek User-Agent, ponieważ niektóre kanały RSS tego wymagają.

    // 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(())
    }
    
  10. Teraz potwierdźmy, że możemy skompilować i uruchomić, klikając pozycję Uruchom>bez debugowania (lub naciskając Ctrl+F5). Jeśli widzisz nieoczekiwane komunikaty, upewnij się, że pomyślnie ukończono samouczek Hello, world! (Rust with VS Code).

    W edytorze tekstu znajdują się również polecenia Debug i Run. Alternatywnie, w wierszu polecenia w folderze rss_reader wpisz cargo run, który skompiluje, a następnie uruchomi program.

    Polecenia debugowania i uruchamiania osadzone w edytorze tekstów

    W okienku terminalu programu VS Code można zobaczyć, że Cargo pomyślnie pobiera i kompiluje pakiet Windows , buforując wyniki i używając ich, aby kolejne kompilacje były ukończone w krótszym czasie. Następnie kompiluje przykład i uruchamia go, wyświetlając listę tytułów wpisów w blogu.

    Lista tytułów wpisu w blogu

Programowanie w języku Rust dla systemu Windows jest równie proste. Jednak pod maską wiele miłości wkłada się w tworzenie narzędzi, aby Rust mógł analizować pliki .winmd oparte na ECMA-335 (Infrastruktura Języka Wspólnego, czyli CLI), a także jak również wiernie zachowywać interfejs binarny aplikacji oparty na modelu COM (ABI) w czasie wykonywania, z myślą zarówno o bezpieczeństwie, jak i wydajności.

Wyświetlanie pola komunikatu

Powiedzieliśmy, że rust dla systemu Windows umożliwia wywoływanie dowolnego interfejsu API systemu Windows (przeszłości, teraźniejszości i przyszłości). W tej sekcji pokażemy kilka pól komunikatów systemu Windows.

  1. Podobnie jak w przypadku projektu RSS, w wierszu poleceń wpisz polecenie cd, aby przejść do folderu z projektami Rust.

  2. Utwórz nowy projekt o nazwie message_box i otwórz go w programie VS Code:

    > cargo new message_box
    >     Created binary (application) `message_box` package
    > cd message_box
    > code .
    
  3. W programie VS Code otwórz plik Cargo.tomli dodaj zależności systemu Windows dla tego projektu:

     # message_box\Cargo.toml
     ...
    
     [dependencies.windows]
     version = "0.43.0"
     features = [
         "Win32_Foundation",
         "Win32_UI_WindowsAndMessaging",
     ]
    
  4. Teraz otwórz plik projektu src/main.rs i dodaj use deklaracje z nowymi przestrzeniami nazw zgodnie z poniższym przykładem. Na koniec dodaj kod, aby wywołać funkcje MessageBoxA i MessageBoxW. Dokumentacja interfejsu API systemu Windows jest napisana głównie z myślą o języku C/C++, dlatego warto porównać dokumenty interfejsu API z dokumentami dotyczącymi projekcji Rust w oknach : MessageBoxA (Rust) i MessageBoxW.

    // 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);
        }
    }
    

    Jak można zauważyć, musimy użyć tych Win32 API w unsafe sekcji kodu (zobacz Bloki niebezpieczne). Zwróć również uwagę na makra s! i w!, które tworzą argumenty LPCSTR i LPCWSTR z literałów ciągu Rust UTF-8; podobnie jak utworzyliśmy HSTRING za pomocą makra h! dla rss_reader. Rust natywnie obsługuje Unicode z ciągami UTF-8, więc używanie interfejsów API Windows dla szerokiego Unicode (z sufiksem W) jest preferowane nad interfejsami API ANSI (z sufiksem A). Może to być ważne, jeśli używasz tekstu innego niż angielski w kodzie.

Tym razem podczas kompilowania i uruchamiania rust wyświetla dwa pola komunikatów systemu Windows.