Based on "Future Possibilities for .NET Core and WASI (WebAssembly on the Server) | OD108", published May 27, 2022 by Steve Sanderson (SteveSandersonMS on Github, @stevensanderson on Twitter). Video at https://youtu.be/A0vz_BWxIMc.
Prerequisites
.NET Version
.NET 7 or later is required. I used ".NET 7 Preview 4", downloaded from: https://dotnet.microsoft.com/en-us/download/dotnet/7.0.
On Windows
I did not use the Installer. Rather, I downloaded the "Binaries" and unzipped them to a local folder. Then I added the root of that local folder to the front of the PATH environment variable, in a command prompt.
I also used the "Developer Command Prompt for VS 2022" command prompt.
On Mac
I installed .NET 7 Preview 4 using the installer.
WASI Runtime
To run the final .wasm file, I used wasmtime which I installed from here: https://wasmtime.dev/
I also ran it under wasmer, Installed from here: https://wasmer.io/
Build and Run
From a terminal or command prompt, create a new dotnet console project and "cd" into it:
dotnet new console -o HelloWasi
cd HelloWasi
Then run it to make sure it works:
dotnet run
It will just say "Hello world" or something like that. Update Program.cs to output something more interesting. Replace Program.cs with this code:
using System.Runtime.InteropServices;
System.Console.WriteLine($"Hello world! The time is {DateTime.UtcNow.ToLongTimeString()}");
System.Console.WriteLine($"OSArchitecture: {RuntimeInformation.OSArchitecture}");
System.Console.WriteLine($"OSDescription: {RuntimeInformation.OSDescription}");
System.Console.WriteLine($"FrameworkDescription {RuntimeInformation.FrameworkDescription}");
System.Console.WriteLine($"ProcessArchitecture {RuntimeInformation.ProcessArchitecture}");
System.Console.WriteLine($"RuntimeIdentifier {RuntimeInformation.RuntimeIdentifier}");
Build and run again:
dotnet build
dotnet run
You should see output something like this. Note what it says for "OSArchitecture"
Hello world! The time is 1:34:03 AM
OSArchitecture: X64
OSDescription: Microsoft Windows 10.0.19044
FrameworkDescription .NET 7.0.0-preview.4.22229.4
ProcessArchitecture X64
RuntimeIdentifier win10-x64
On macOS you'd get something like this:
Hello world! The time is 2:51:07 PM
OSArchitecture: X64
OSDescription: Darwin 19.6.0 Darwin Kernel Version 19.6.0: Tue Feb 15 21:39:11 PST 2022; root:xnu-6153.141.59~1/RELEASE_X86_64
FrameworkDescription .NET 7.0.0-preview.4.22229.4
ProcessArchitecture X64
RuntimeIdentifier osx.10.15-x64
Now let's update the project to target WebAssembly instead.
Add the Wasi.Sdk package:
dotnet add package Wasi.Sdk --prerelease
Or update the .csproj file to include this:
<ItemGroup>
<PackageReference Include="Wasi.Sdk" Version="0.1.1" />
</ItemGroup>
Now when you do:
dotnet build
it will create HelloWasi.wasm next to the HelloWasi..exe file:
bin\Debug\net7.0\HelloWasi.wasm
I'll be a single 16 MB file, because it contains all of the required .NET code.
Using Wasmtime, we can run this .wasm file:
wasmtime bin\Debug\net7.0\HelloWasi.wasm
Note the "OSArchitecture" field in the output:
Hello world! The time is 01:33:31
OSArchitecture: Wasm
OSDescription: Browser
FrameworkDescription .NET 7.0.0-dev
ProcessArchitecture Wasm
RuntimeIdentifier browser-wasm
Same exact .wasm file can run on any platform that supports WASI. I tried it under wsl2 using wasmtime. Also works under MacOS
Also tried the wasmer runtime.