Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Use the .NET, TypeScript, or Rust SDK to run a command in Windows process isolation. Each example creates a sample input, allow the workload to read it, and grant write access to a separate output folder. Network and UI permissions remain denied.
Your host app creates the policy and handles the result. The command runs inside MXC; the rest of the host app does not.
The examples use the MXC 1.0 V1 SDK APIs. The V1 SDKs use the stable 1.0.0 schema internally, so you don't specify a schema version in your request. See Choose a compatible schema.
Prerequisites
You need:
- Windows 11, version 24H2 or later, with a supported ProcessContainer environment.
- For C#, the .NET 8 SDK or later and the
Microsoft.Mxc.SdkNuGet package. - For TypeScript, npm, the
@microsoft/mxc-sdkpackage, and Node.js 24.21.0 or later in the Node.js 24 release line, or Node.js 26.8.0 or later. - For Rust, a stable Rust toolchain with the MSVC build tools, and the
mxc-sdkcrate. See Set up your Rust development environment on Windows. - A writable working directory and PowerShell for the setup commands.
The instructions use the MXC 1.0 packages from NuGet.org, npm, and crates.io. No MXC source build is required.
Check platform support before you run the example. A supported Windows version doesn't guarantee that every optional feature is available.
On some hosts, MXC runs process isolation in an AppContainer-based fallback tier. That tier needs one-time preparation of the system drive and the null device, and the null-device setting resets at every restart. When preparation is missing, MXC's host probe returns a warning that names the wxc-host-prep.exe subcommand to run. The TypeScript example prints these warnings from getPlatformSupport(), and you can also check a host by running wxc-exec.exe --probe. Because wxc-host-prep.exe requires administrator approval, have an administrator run the recommended command rather than running it from your app. For details, see Host preparation.
1. Create a project
Create a console app and add the MXC package from NuGet.org:
dotnet new console -n MxcQuickstart
Set-Location MxcQuickstart
dotnet add package Microsoft.Mxc.Sdk
2. Define and run the workload
Process isolation fits this short-lived command because it needs selected host files and no retained environment. Other workloads can require a different containment type.
The host creates workspace\input and workspace\output beneath the project directory. The contained command reads input.txt and writes result.txt. It doesn't receive write access to its input directory or access to other project files.
The host supplies a small, explicit environment instead of inheriting its own variables. When you supply an environment for a Windows ProcessContainer workload, include both SystemRoot and LOCALAPPDATA. MXC rejects the request before launch if either one is missing. The example points LOCALAPPDATA, TEMP, and TMP at the granted output directory so that temporary and per-user files stay within the policy.
Replace Program.cs with:
using Microsoft.Mxc.Sdk.V1;
if (!OperatingSystem.IsWindows())
{
Console.Error.WriteLine("This example requires Windows.");
return 1;
}
try
{
var support = MxcPlatform.GetPlatformSupport();
if (!support.IsSupported ||
!support.AvailableMethods.Contains(ContainmentBackend.ProcessContainer))
{
Console.Error.WriteLine(support.Reason ?? "Windows ProcessContainer is unavailable.");
return 1;
}
string inputDirectory = Path.GetFullPath(@"workspace\input");
string outputDirectory = Path.GetFullPath(@"workspace\output");
string outputFile = Path.Combine(outputDirectory, "result.txt");
string commandInterpreter = Path.Combine(Environment.SystemDirectory, "cmd.exe");
Directory.CreateDirectory(inputDirectory);
Directory.CreateDirectory(outputDirectory);
File.WriteAllText(Path.Combine(inputDirectory, "input.txt"), "Hello from MXC!\n");
var request = new ContainerRequest(
$"\"{commandInterpreter}\" /d /c type input.txt > \"{outputFile}\"")
{
Containment = new Containment.Process(),
Filesystem = new FilesystemPolicy
{
ReadonlyPaths = { inputDirectory, commandInterpreter },
ReadwritePaths = { outputDirectory },
},
// Omitted network and UI permissions remain denied.
WorkingDirectory = inputDirectory,
Environment = new()
{
["SystemRoot"] = Environment.GetFolderPath(Environment.SpecialFolder.Windows),
["LOCALAPPDATA"] = outputDirectory,
["TEMP"] = outputDirectory,
["TMP"] = outputDirectory,
},
TimeoutMs = 30_000,
};
ExecutionResult result = await MxcContainer.RunAsync(request);
Console.Write(result.Stdout);
Console.Error.Write(result.Stderr);
foreach (string warning in result.Warnings)
{
Console.Error.WriteLine(warning);
}
if (result.TimedOut)
{
Console.Error.WriteLine("The workload exceeded its timeout.");
return 1;
}
Console.WriteLine($"Sandbox exited with code {result.ExitCode}");
if (result.ExitCode == 0)
{
Console.Write(File.ReadAllText(outputFile));
}
return result.ExitCode;
}
catch (MxcException ex)
{
Console.Error.WriteLine(ex);
if (ex.Remediation is not null)
{
Console.Error.WriteLine(ex.Remediation);
}
return 1;
}
Run the app:
dotnet run
Each version prints:
Sandbox exited with code 0
Hello from MXC!
You can also inspect workspace\output\result.txt.
3. Verify a denied operation
Change only the output file declaration so the command attempts to write into the read-only input directory:
string outputFile = Path.Combine(inputDirectory, "blocked.txt");
Run the app again without changing the policy. Expect an access-denied error and a nonzero exit code, with no new workspace\input\blocked.txt file. Restore the original output file declaration and confirm that the permitted operation still succeeds.
If the permitted run fails, distinguish host setup or configuration errors from a resource denial. Use Learning Mode to investigate the latter; don't broaden the policy automatically.
4. Adapt the example
Replace the sample command and inputs with a trusted representative workload. Review required tool binaries, libraries, temporary files, and outputs. Add network or UI access only when the task requires it and the selected backend can enforce the intended restrictions.
Test permitted and denied operations on every target host. When you use Learning Mode to refine the policy, review each observation and finish with an enforcing run without learning or audit settings.
Optional: use a coding agent
Give your agent the target platforms, SDK language and version, command, required resources, lifecycle, and isolation goals. You can adapt this prompt:
Use the MXC Learn quickstart and the documentation for my installed SDK release.
Integrate this workload through the .NET, TypeScript, or Rust SDK used by this project.
First identify the command, target platforms, input and output paths, network
and UI requirements, and whether state must persist between commands.
Explain the containment choice and create the narrowest policy that fits.
Run both permitted and denied cases and report the effective permissions.
Do not execute the workload outside MXC to get around a failure. Ask for my
approval before expanding access, changing host settings, or using permissive
Learning Mode. Treat observed resource access as evidence, not automatic grants.
Review the agent's assumptions and resulting policy. An agent can assist with integration, but trusted host code or a person must approve changes to the workload's authority.
Next steps
- Review MXC architecture and containment models before using persistent or specialized backends.
- Learn how to author and validate an MXC policy.
- Compare MXC containment options and platform support.
- Review the complete Learning Mode workflow.
- Adapt the MXC policy examples to other workloads.
- Find SDK packages and release notes in MXC releases.
Windows developer