ClickOnce is a cool decentralized way of distributing applications on Windows. I’ll demonstrate distributing a Rust language application using ClickOnce. The game uses Rust/WinRT to build a UI on top of the Windows Runtime. ClickOnce shipped with .NET Framework 2.0 in January of 2006. Almost 15 years later, .NET 5.0 was announced with improved ClickOnce support. A simple .NET 5.0 app is used to launch the bundled game.

Published to GitHub Pages

I published the app to GitHub Pages in an orphaned gh-pages branch. A concern of this approach may be bloat for the GitHub repository. One way to keep the repository smaller is to not keep history in that branch by force pushing to it. I published the file and the entire folder.

Image for post
Image for post
Image for post
Image for post

The folder contains all the files with a extension. To avoid some checksum validation problems due to different line endings, I added a file.

Image for post
Image for post

The published files were copies from the ClickOnce the app.publish folder. The ClickOnce can be tested locally by double clicking on the Minesweeper.application. The .NET launcher can be tested without ClickOnce by just clicking on the Minesweeper.exe. The Rust app can be tested without the .NET launcher by clicking on the minesweeper-rs.exe.

Image for post
Image for post

ClickOnce Publishing

I put all the files needed to publish via ClickOnce in a folder named . After building the Rust app with , I just call . It launches to build the .NET launcher, create the ClickOnce Application Manifest, create the ClickOnce Deployment Manifest, and sign both of them, creating the folder above. The targets come with any version of Visual Studio, include Visual Studio Build Tools. The targets to sign the manifests do not work with yet, so stick to . In PowerShell, I can add add it to the environment variable with

Image for post
Image for post

FYI, Visual Studio Build Tools are available using winget. Run . There are a few ways to install winget, but I usually just download and launch the latest .appxbundle from the most recent release on the releases page. Running the Visual Studio Installer app will help you update if you wish to.

Image for post
Image for post

You could build the ClickOnce manifests by hand, but it is much easier to let the MSBuild targets do it for you using a publish profile. A publish profile is itself an MSBuild file containing a bunch of properties and items.

Image for post
Image for post
Image for post
Image for post

The was generated from a Build > Publish wizard in Visual Studio. I’m not sure what the minimal set of properties are.

I moved a couple of the properties into a file that are specific to a particular user and shouldn’t be committed. The is the base URL for the deployments. The is the certificate of my locally installed code signing certificate.

.NET Launcher

The .NET app that starts the Rust app is a very basic Windows Form application.

The project file is also straight forward, but take the time to read how .NET 5.0 has changed things, especially :

Windows desktop APIs (including Windows Forms, WPF, and WinRT) will only be available when targeting net5.0-windows. You can specify an operating system version, like or ( for Windows October 2018 Update). You need to target a Windows 10 version if you want to use WinRT APIs.

I added the and properties to that project file, but you leave them out and pass them in or override them by passing them as parameters to on the command line, such as and .

Wrapping it Up

I enjoy seeing Rust being used more for desktop application development. Projects like Rust/WinRT and gtk-rs are making desktop application development more accessible from Rust. I’m looking forward to even better support for WinUI 3 and GTK 4.0. Even though ClickOnce is a .NET component, it can be used to distribute desktop apps built in Rust as well.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store