Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O tópico anterior introduziu Rust para Windows e o crate de janelas.
Agora vamos experimentar o Rust para Windows escrevendo um aplicativo de console simples que baixa os títulos de postagens de blog de um feed RSS (Really Simple Syndication).
Abra um prompt de comando (
cmd.exe
) ecd
para uma pasta onde você deseja manter seus projetos Rust.Usando o Cargo, crie um novo projeto Rust chamado rss_readere
cd
para a pasta recém-criada:> cargo new rss_reader > Created binary (application) `rss_reader` package > cd rss_reader
Em seguida, abra o projeto rss_reader no VS Code.
code .
Vamos implementar o projeto principal rss_reader. Primeiro, abra o
Cargo.toml
arquivo na raiz do projeto. UmCargo.toml
arquivo é um arquivo de texto que descreve um projeto em Rust, incluindo as dependências que ele tem.Adicione uma dependência nas janelas crate, conforme mostrado na listagem abaixo. A caixa de janelas é grande. Para manter os tempos de build rápidos, selecionaremos apenas as características
Foundation_Collections
eWeb_Syndication
necessárias para este código.# Cargo.toml ... [dependencies.windows] version = "0.43.0" features = [ "Foundation_Collections", "Web_Syndication", ]
Em seguida, abra o arquivo de código-fonte do
src/main.rs
projeto. Lá, você encontrará o código padrão "Olá, mundo!" do Cargo. Adicione a seguinte instrução use ao início domain.rs
:// src\main.rs use windows::{ core::*, Foundation::Uri, Web::Syndication::SyndicationClient }; fn main() { println!("Hello, world!"); }
O uso da declaração reduz o caminho para os tipos que usaremos. Há o tipo de Uri que mencionamos anteriormente.
Para criar uma novade Uri
, substitua a função de principal padrão do Cargo por esta: // src\main.rs ... fn main() -> Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; Ok(()) }
Observe que o tipo de retorno da função de principal do
é umde Resultado , de windows::core:: . Isso facilitará as coisas, pois é comum lidar com erros de APIs do sistema operacional (SO). windows::core::Result nos auxilia na propagação de erros e em um tratamento mais conciso desses problemas.Você pode ver o operador de ponto de interrogação no final da linha de código. Para economizar na digitação, fazemos isso para usar a lógica de propagação de erros e curto-circuito do Rust. Isso significa que não precisamos fazer um monte de tratamento manual de erros para este exemplo simples. Para obter mais informações sobre esse recurso do Rust, consulte O operador ? para facilitar o tratamento de erros.
Observe também o h! macro das janelas crate. Usamos isso para construir uma referência de HSTRING a partir de um literal de string Rust. A API do WinRT usa HSTRING extensivamente para valores de cadeia de caracteres.
Para baixar o feed RSS, criaremos um novo SyndicationClient.
// src\main.rs ... fn main() -> windows::core::Result<()> { let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?; let client = SyndicationClient::new()?; Ok(()) }
A função nova é um construtor em Rust. Todos os objetos no crate windows seguem a convenção Rust e nomeiam seus construtores new.
Agora podemos usar o SyndicationClient para recuperar o 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(()) }
Como RetrieveFeedAsync é uma API assíncrona, usamos a função de obtenção de bloqueio para manter o exemplo simples. Como alternativa, poderíamos usar o
await
operador dentro de umaasync
função para aguardar cooperativamente os resultados. Um aplicativo mais complexo com uma interface gráfica do usuário frequentemente usaráasync
.Agora podemos iterar sobre os itens resultantes e imprimir apenas os títulos. Você também verá algumas linhas extras de código abaixo para definir um cabeçalho de agente de usuário, já que alguns feeds RSS exigem isso.
// 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(()) }
Agora, vamos confirmar se podemos compilar e executar clicando em Executar>Executar sem Depuração (ou pressionando Ctrl+F5). Se você vir mensagens inesperadas, verifique se concluiu com êxito o tutorial Olá, mundo! (Rust com VS Code).
Também há comandos Depurar e Executar inseridos no editor de texto. Como alternativa, a partir de um prompt de comando na pasta
rss_reader
, digitecargo run
, que irá compilar e executar o programa.No painel terminal do VS Code
, você pode ver que o Cargo baixa e compila com êxito as janelas engradado, armazenando os resultados em cache e usando-os para concluir as compilações subsequentes em menos tempo. Em seguida, ele cria o exemplo e o executa, exibindo uma lista de títulos de postagem no blog.
Isso é tão simples quanto é programar o Rust para Windows. Por trás das cenas, no entanto, há muito cuidado na criação das ferramentas para que o Rust possa analisar arquivos .winmd
com base no ECMA-335 (Common Language Infrastructure, ou CLI), e também respeitar fielmente a interface binária de aplicativo (ABI) baseada em COM durante o tempo de execução, sempre considerando segurança e eficiência.
Mostrando uma caixa de mensagem
Dissemos que o Rust para Windows permite que você chame qualquer API do Windows (passado, presente e futuro). Portanto, nesta seção, mostraremos algumas caixas de mensagem do Windows.
Assim como fizemos para o projeto RSS, no prompt de comando, execute
cd
para a pasta com seus projetos do Rust.Crie um novo projeto chamado message_box e abra-o no VS Code:
> cargo new message_box > Created binary (application) `message_box` package > cd message_box > code .
No VS Code, abra o
Cargo.toml
, e então adicione as dependências do Windows para este projeto:# message_box\Cargo.toml ... [dependencies.windows] version = "0.43.0" features = [ "Win32_Foundation", "Win32_UI_WindowsAndMessaging", ]
Agora, abra o arquivo do
src/main.rs
projeto e adicione asuse
declarações com os novos namespaces (conforme mostrado abaixo). E, por fim, adicione código para chamar as funções MessageBoxA e MessageBoxW . Os documentos da API do Windows são escritos principalmente com C/C++ em mente, portanto, é útil comparar os documentos da API com os documentos das projeções do Rust nas janelas crate: do MessageBoxA (Rust) e 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); } }
Como você pode ver, devemos usar essas APIs Win32 em um
unsafe
bloco (consulte blocos não seguros). Observe também os macross! ew! , que criam argumentosLPCSTR eLPCWSTR a partir de literais de cadeia de caracteres Rust UTF-8; assim como criamos uma HSTRINGcom o macro h! pararss_reader . O Rust é, nativamente, Unicode com cadeias de caracteres UTF-8, portanto, usar as APIs amplas do Windows Unicode (sufixo W) é preferencial em vez das APIs ANSI (Sufixo A). Isso pode ser importante se você usar texto não inglês em seu código.
Desta vez, quando você cria e executa, o Rust exibe duas caixas de mensagem do Windows.
Relacionado
Windows developer