Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Dotnet: From Versioned Inputs to Typed Observations

The Dotnet wrapper supplies SDK/build-tool operations and selected host observations. It separates output produced by the SDK from arbitrary application output produced by run, exec, watch or installed tools.

SDK selection, command syntax and a JSON schema's output version are three different inputs.

Acquisition checks the selected SDK

The Design executable discovers dotnet/sdk tags, optionally selects a stable SDK version and prepares an SDK image. Its default minimum is 8.0.100 and version-worker default is two.

Custom middleware warms up the SDK, checks that dotnet --version matches the expected version and verifies root help exposes SDK commands. Specialized help execution captures the appropriate streams and forwards ctx.Environment.

Replay uses cached help. The inspected runner initializer does not assign the catalogue's process dictionary to Environment, so the existence of the forwarding callback alone should not be presented as proof that every declared runtime variable is acquired through this entry point.

The collector's stable-tag policy is separate from the runtime parser's explicitly reviewed RC SDK support.

Generated commands and host-query adapters

Contracts contains generated commands, environments, events, result records and the runner interface. Builders/client and parsers remain implementation types.

DotnetHostCommand complements generated leaf commands with root queries for Version, SDKs, Runtimes and Info. Info remains text; it is not presented as a fully structured inventory.

A command's target version must describe the executable actually selected. Setting binding metadata does not install an SDK, and global.json plus the working directory can change SDK selection.

A complete host-inventory example

This offline example simulates an installed-SDK line. It starts no SDK process and uses the binding version because the host-query adapter does not supply a target here.

using FrenchExDev.Net.BinaryWrapper;
using FrenchExDev.Net.BinaryWrapper.Lib;
using FrenchExDev.Net.BinaryWrapper.Testing;
using FrenchExDev.Net.Dotnet;

var binding = new BinaryBinding
{
    Identifier = new BinaryIdentifier("dotnet"),
    ExecutablePath = "unused",
    DetectedVersion = SemanticVersion.Parse("10.0.401"),
};
var command = new DotnetHostCommand(DotnetHostQuery.Sdks);
var executor = new CommandExecutor(new DictionaryBinaryResolver(binding),
    new FakeProcessRunner([
        new OutputLine("10.0.401 [C:/example/sdk]", OutputSource.StdOut),
    ]));
await foreach (var evt in executor.StreamAsync(
    binding.Identifier, command, DotnetOutputStrategies.Default))
{
    if (evt is DotnetSdkInstalledObserved sdk)
        Console.WriteLine($"{sdk.Version}: {sdk.Directory}");
    if (evt.OutputLine is { } line)
        Console.WriteLine($"{line.Source}: {line.Text}");
    if (evt is DotnetCommandExited exited)
        Console.WriteLine($"SDK query exit: {exited.ExitCode}");
}

A live inventory command must detect the SDK selected for that context rather than infer it from one installed-SDK list entry.

JSON schema version is not SDK version

A generated package command can request JSON and a schema version. This is a construction excerpt:

var command = new DotnetPackageListCommand(version)
{
    Format = "json",
    OutputVersion = "1",
};

The command's string OutputVersion asks Dotnet for package schema 1. An output event's inherited OutputVersion is a SemanticVersion identifying the SDK profile chosen by BinaryWrapper. They share spelling, not meaning or type.

Supported JSON families include package list/search, workload documents and CLI schema documents. Complete evidence preserves unprojected fields. Format guards prevent arbitrary JSON application output from becoming a package or workload record.

SDK diagnostics and application output

Reviewed SDK diagnostic prefixes expose tool-level observations. MSBuild binary logs and custom test logger formats are separate protocols.

Commands that produce arbitrary application/tool output, including run, exec, watch and tool execution, stay raw under the default strategy. An application can supply its own parser factory for a known app protocol, but SDK version alone cannot establish that schema.

DotnetOutputCollector can aggregate retained events and terminal success according to its known diagnostic rules. A human “build succeeded” line is still a milestone before actual process exit.

Environment semantics

DotnetEnvironment includes CLI home, architecture-specific roots, host path, UI language, logo/telemetry configuration, workload notification and related settings.

Most declared numeric booleans use their converter's numeric form. Workload update notification uses textual true/false, so boolean conversion is not uniform across the catalogue.

DOTNET_ROOT(x86) also demonstrates a variable name that is not a C# identifier. The generator uses a safe property-derived assignment flag. with copies preserve explicit assignment state.

These settings configure the SDK process. They do not describe an application's complete environment or automatically select a desired SDK version.

Profiles and validation

Reviewed profiles cover stable SDKs 10.0.100 and 10.0.401, plus the exact 11.0.100-rc.1.26425.128 SDK. Unmatched versions retain raw output and the actual exit. The RC interval is explicitly reviewed rather than inferred from a future stable version.

Tests cover host queries, package/workload/schema projections, diagnostics, JSON retention limits, wrong command contexts, profiles, fresh parser state, terminal failures and generated-command integration.

For a software factory, distinguish the SDK selected to execute a command, SDKs reported as installed, the target framework being built and the output schema requested. The wrapper makes these facts inspectable; the application's build/reproducibility policy decides which combinations are acceptable.

Source snapshot

Source inspection: 2 October 2026. These implementation paths are relative to Net/FrenchExDev in the local ecosystem checkout. The v2 changes are largely uncommitted; these paths identify inspected code, without claiming that public branch links contain it.

  • Dotnet/src/FrenchExDev.Net.Dotnet.Design/Program.cs
  • Dotnet/src/FrenchExDev.Net.Dotnet.Contracts/FrenchExDev.Net.Dotnet.Contracts.csproj
  • Dotnet/src/FrenchExDev.Net.Dotnet/FrenchExDev.Net.Dotnet.csproj
  • Dotnet/doc/TYPED-OUTPUT.md
  • Dotnet/test/FrenchExDev.Net.Dotnet.Tests

Previous: GitLab.Cli · Implementation index · Series index · Next: WinGet

⬇ Download