Files
WSL/doc/docs/api-reference/csharp/end-to-end-example.md
0704fa160b Update WSLC SDK API documentation (#41677)
* Update WSLC SDK API documentation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update docs

* Update docs

* Quick fixes

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Craig Loewen <crloewen@microsoft.com>
2026-09-29 10:14:54 -04:00

3.3 KiB

End-to-End Example

The example below shows one full lifecycle matching the C API example:

  1. Check prerequisites
  2. Print SDK version
  3. Create a session (4 CPUs, 4 GB RAM)
  4. Pull alpine:latest
  5. Configure an init process (/bin/echo "Hello from WSL Container!")
  6. Create and start the container
  7. Wait for the init process to exit
  8. Print exit code
  9. Stop and delete the container
  10. Terminate the session
using Microsoft.WSL.Containers;
using System;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task<int> Main()
    {
        // 0. Check prerequisites
        var missing = WslcService.GetMissingComponents();
        foreach (Component component in missing)
        {
            if (component == Component.SdkNeedsUpdate)
            {
                Console.WriteLine("This application is incompatible with the installed WSL runtime.");
                return 1;
            }
        }
        if (missing.Count != 0)
        {
            Console.WriteLine("WSL components are missing. Run: wsl --install");
            return 1;
        }

        var ver = WslcService.GetVersion();
        Console.WriteLine($"WSL version: {ver.Major}.{ver.Minor}.{ver.Revision}");

        // 1. Create a session
        var sessionSettings = new SessionSettings("MyApp", @"C:\WslcData")
        {
            CpuCount = 4,
            MemorySizeInMB = 4096
        };

        var session = new Session(sessionSettings);
        session.Start();

        // 2. Pull an image
        var pullOp = session.PullImageAsync(new PullImageOptions("docker.io/library/alpine:latest"));
        pullOp.Progress = (op, progress) =>
            Console.WriteLine($"Pull: {progress.Status} {progress.CurrentBytes}/{progress.TotalBytes}");
        await pullOp;

        // 3. Configure an init process
        var initProcSettings = new ProcessSettings
        {
            CommandLine = new[] { "/bin/echo", "Hello from WSL Container!" },
            OutputMode = ProcessOutputMode.Event
        };

        // 4. Configure and create a container
        var containerSettings = new ContainerSettings("alpine:latest")
        {
            Name = "hello-container",
            InitProcess = initProcSettings
        };

        var container = session.CreateContainer(containerSettings);

        // 5. Subscribe to init process events before starting
        var exited = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);

        container.InitProcess.OutputReceived += data =>
            Console.Write(Encoding.UTF8.GetString(data));
        container.InitProcess.Exited += code =>
            exited.TrySetResult(code);

        // 6. Start the container
        container.Start();

        // 7. Wait for the init process to exit (30-second timeout)
        var completed = await Task.WhenAny(exited.Task, Task.Delay(TimeSpan.FromSeconds(30)));
        int exitCode = completed == exited.Task ? exited.Task.Result : -1;
        Console.WriteLine($"Process exited with code: {exitCode}");

        // 8. Clean up
        if (container.State == ContainerState.Running)
        {
            container.Stop(Signal.SIGTERM, TimeSpan.FromSeconds(10));
        }
        container.Delete(DeleteContainerOption.None);
        session.Terminate();

        return exitCode;
    }
}