DesktopHost.Processes
0.2.0
See the version list below for details.
dotnet add package DesktopHost.Processes --version 0.2.0
NuGet\Install-Package DesktopHost.Processes -Version 0.2.0
<PackageReference Include="DesktopHost.Processes" Version="0.2.0" />
<PackageVersion Include="DesktopHost.Processes" Version="0.2.0" />
<PackageReference Include="DesktopHost.Processes" />
paket add DesktopHost.Processes --version 0.2.0
#r "nuget: DesktopHost.Processes, 0.2.0"
#:package DesktopHost.Processes@0.2.0
#addin nuget:?package=DesktopHost.Processes&version=0.2.0
#tool nuget:?package=DesktopHost.Processes&version=0.2.0
desktop-host
.NET building blocks for the local host process of a desktop app — the long-running .NET process that does an app's local work (files, models, devices) next to its window.
Such a process ends up writing the same platform code for itself, and gets it wrong in the same quiet ways:
- Durable files — a write that survives a crash or a power cut, the brief refusals of virus scanners and sync clients, finding which process holds a file
- Its own log — a file log that rotates and never fills the disk
- The processes it starts — workers and helpers that start, report ready, restart within limits and never outlive it
Status: 0.2.0 — DesktopHost.Files, DesktopHost.Logging and DesktopHost.Processes on NuGet.
See SCOPE.md for what belongs here.
Packages
DesktopHost.Files
Durable file writes and the reads that go with them.
AtomicFile— replace a text file so that a reader sees the whole old or the whole new document, never a part: temp sibling, flush to disk, one atomic rename (a POSIX-semantics rename on Windows), retried for about two seconds through brief locks, with an exception that names who held the file. Shared reads (ReadAllTextShared,ReadLinesShared, and…IfExistsforms that answer "absent" only for a missing file) never block such a write.FileRetry— delete or move a file or directory through the seconds a virus scanner or sync client holds it.FileLockHolders— name the processes holding a file open (Windows Restart Manager; empty elsewhere).
using DesktopHost.Files;
// A reader never sees half of this, even while it is being written.
await AtomicFile.WriteAllTextAsync(path, json);
// null only when the file is not there; any other failure throws.
string? text = await AtomicFile.ReadAllTextSharedIfExistsAsync(path);
// Outlasts a scanner holding a just-extracted file.
FileRetry.MoveDirectory(staging, target, logger);
DesktopHost.Logging
A file log for Microsoft.Extensions.Logging that rotates and never fills the disk.
RollingFileLoggerProvider—{prefix}-{yyyy-MM-dd}.logper UTC day, continued in{prefix}-{yyyy-MM-dd}.1.log,.2.log… at a size limit; old files removed by age and by count whenever a file is opened. Lines from any thread come out whole; another process can read the file as it grows; entries after shutdown are dropped rather than thrown.RollingFileLoggerOptions— directory and prefix (required),RetentionPrefix(clear the old files of several writers that share a prefix),RetainedFileTimeLimit(7 days),RetainedFileCountLimit(31),FileSizeLimitBytes(64 MiB),TimeProvider.
using DesktopHost.Logging;
builder.Logging.AddRollingFile(logDirectory, "host");
// Each worker writes its own file; any of them clears the old files of all.
builder.Logging.AddRollingFile(logDirectory, $"worker-{id}", o => o.RetentionPrefix = "worker");
DesktopHost.Processes
Supervision of the long-lived processes a host starts — on top of ChildProcessGuard, which keeps them from outliving the host.
ProcessSupervisor— start, wait until ready, start again after an unexpected exit within limits, stop the child's own way before killing its whole tree. A process replaced on request or stopped never triggers a restart; events are raised outside the supervisor's lock, so a handler can call back in.ProcessSupervisorOptions—Command(resolved at each start; the child gets only the environment it names),Ready+ReadyTimeout,RestartPolicy(Delays,StableAfter,IsPermanentExit),StopPolicy(GracefulStop,GracefulTimeout,CloseMainWindow),Guardian(share one per host),Logger,StderrTailLines.
using DesktopHost.Processes;
var env = SupervisedCommand.SafeEnvironment();
env["WORKER_PORT"] = port.ToString();
await using var worker = new ProcessSupervisor(new ProcessSupervisorOptions
{
Name = "worker",
Guardian = guardian, // one per host
Command = () => new SupervisedCommand(workerPath, ["--serve"], env),
Ready = async (process, ct) => await WaitForHelloAsync(process.StandardOutput, ct),
Stop = { GracefulStop = (process, ct) => process.StandardInput.WriteLineAsync("quit".AsMemory(), ct) },
});
await worker.StartAsync();
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- ChildProcessGuard (>= 1.4.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.13)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.