Runic.Platform 0.8.0-preview.2

This is a prerelease version of Runic.Platform.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Runic.Platform --version 0.8.0-preview.2
                    
NuGet\Install-Package Runic.Platform -Version 0.8.0-preview.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Runic.Platform" Version="0.8.0-preview.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Runic.Platform" Version="0.8.0-preview.2" />
                    
Directory.Packages.props
<PackageReference Include="Runic.Platform" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Runic.Platform --version 0.8.0-preview.2
                    
#r "nuget: Runic.Platform, 0.8.0-preview.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Runic.Platform@0.8.0-preview.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Runic.Platform&version=0.8.0-preview.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Runic.Platform&version=0.8.0-preview.2&prerelease
                    
Install as a Cake Tool

Runic.Platform

Host-independent native-service contracts for Runic applications.

Preview API targeting .NET 10. Native providers are explicitly selected; this package has no Desktop or ASP.NET Core dependency. Runic.Application.Views.Desktop selects one for each window with services.AddRunicPlatformServices().

Services return PlatformResult<T>: Success, Unavailable with a PlatformUnavailableReason, or Failed with a PlatformFailureCode. Operations without a value return PlatformResult<PlatformUnit>. The type names carry the Platform prefix so they do not collide with System.Reactive.Unit and similar names when both namespaces are imported.

Branch on the failure code. When a provider observed a native error, Failed.Diagnostic carries a PlatformDiagnostic with its domain (HRESULT, Win32, errno, an NSError/GError domain or a D-Bus error name), numeric code and, where the operating system's error table describes the code, its message. It is for logs and support, not display. Free-form text from native services (GError and D-Bus messages, NSError descriptions) is left out, so a diagnostic contains no paths.

IFileDialogs.OpenDirectoryAsync(new OpenDirectoryOptions()) returns a PickerResult<IDirectoryLease> for one existing local directory. Keep the selected lease alive while C# filesystem operations use LocalPath; it retains native access until disposal or presentation close. The path preserves the selected identity, including Unicode and escaped filename characters. Native paths that cannot be represented exactly in C# are refused. Leases and native grants remain in C#; expose only application DTOs to a frontend.

Presentation close releases every lease the presentation still owns; on macOS this ends security-scoped access, and LocalPath throws once closing starts. Native owner closure alone does not release leases. When application work that uses a lease can outlive the window, such as recovery owned by an AcceptedWorkScope, drain that work before stopping the PresentationLifetime, or dispose the lease at the end of the work itself:

await acceptedWork.DisposeAsync(); // Work using lease.LocalPath has finished.
await presentationLifetime.DisposeAsync(); // Releases remaining leases.

User dismissal returns Dismissed, caller cancellation throws OperationCanceledException, and presentation shutdown returns Unavailable(OwnerClosed). The platform.directories.open capability reports availability when using PresentationFiles. Existing file-only implementations remain compatible and report directory selection unavailable. A custom IPickerBackend that implements OpenDirectoryAsync must also return true from SupportsDirectorySelection; PresentationFiles always calls the backend's method and throws InvalidOperationException if an undeclared backend returns a result other than Unavailable.

PickerResult<T>.Selected and PlatformResult<T>.Success deconstruct, so a caller can match and take the value in one pattern:

if (await files.OpenFileAsync(new()) is PickerResult<IReadFileLease>.Selected(var lease))
{
    await using (lease) { /* read */ }
}

Window services

IWindowPlatformServices groups the file dialogs, text clipboard and file launcher of one window, and reports their capabilities together under WindowPlatformServices.CapabilityIds. Host adapters register it, and its parts, per window scope through services.AddRunicPlatformServices(), so a ViewModel can take IFileDialogs, ITextClipboard, IDesktopFileLauncher or IWindowPlatformServices in its constructor. Runic.Application.Views.Desktop binds them to the native window when it opens. A host without a native owner registers WindowPlatformServices.Unavailable(reason), whose operations and capabilities all report that reason. Tests can use the same instance.

IDesktopSettings is application-scoped, so AddRunicPlatformServices() registers one singleton for it. A host or platform without a provider registers DesktopSettings.Unavailable(reason): reads return Unavailable(reason), and a watch emits that value once and then waits. IDesktopNotifications is registered the same way; without a provider it is DesktopNotifications.Unavailable(reason), whose requests return Unavailable(reason) and which never raises Activated.

Privileged actions

IDesktopPrivilegedActions runs a step the application declared at build time, a fixed program with bounded arguments, as the administrator after the platform's authorization prompt. The program ran is Success with its exit code; a refused authorization is Failed(PermissionDenied), a dismissed prompt Failed(UserDismissed), and no authorization service Unavailable. Arguments are an argument vector, never a shell command line. DesktopPrivilegedActions.Unavailable(reason) is the provider for hosts and platforms without one. Linux uses Polkit and pkexec through Runic.Platform.Linux.Polkit, Windows a UAC-elevated helper through Runic.Platform.Windows.Elevation, and macOS a launch daemon and Authorization Services through Runic.Platform.MacOS (guide).

Declare privileged actions

Declarations are PrivilegedActionDeclaration values that this package's build targets generate from RunicPrivilegedAction items, in any project that references Runic.Platform as a package:

<ItemGroup>
  <RunicPrivilegedAction Include="org.example.app.activate"
                         Program="/usr/libexec/example/example-helper"
                         Verb="activate"
                         Description="Activate a system configuration"
                         Message="Authentication is required to activate the system configuration."
                         MaximumArguments="1"
                         ArgumentPattern="[A-Za-z0-9._+-]+" />
</ItemGroup>
Metadata Meaning
Item identity The action ID: lowercase reverse-DNS, at least two segments, the same on every platform.
Program The absolute, normalized Unix path of the privileged program. Linux runs it there; other platforms derive their own location from it unless their metadata below says otherwise. Required.
Verb The first argument, which selects the action. Every action needs its own verb, also across programs, and an action without a verb is allowed only on its own (RUNICPA003).
Description, Message What the authorization prompt shows, passed unchanged to the platform packages. Both required.
MaximumArguments Arguments accepted after the verb, 0 to 64. Default 0.
ArgumentPattern A .NET regular expression every argument after the verb must match completely, evaluated with RegexOptions.NonBacktracking.
Name The generated property name, when the last ID segment does not make a good one.
WindowsProgram Windows only: the elevated helper, as a path relative to the application's directory (such as helpers\example-helper.exe) or an absolute path. Default: the file name of Program with .exe, in the application's directory.
MacProgram macOS only: the helper, as a path relative to the application bundle (such as Contents/MacOS/example-helper) or an absolute path.

Platform packages read further metadata of their own, such as Polkit's IconName and AllowActive; see their guides. Metadata no package reads is ignored.

Each build validates the items and writes PrivilegedActions.g.cs under obj/.../runic-privileged/: an internal static partial class with one PrivilegedActionDeclaration property per action and All. The application and its privileged program both use it. Invalid items are build errors RUNICPA001 to RUNICPA009 and RUNICPA011, described in the diagnostics catalog.

Property Default
RunicPrivilegedActionsClassName PrivilegedActions
RunicPrivilegedActionsNamespace $(RootNamespace)
RunicPrivilegedActionsReservedNames All, MacOSDaemon and WindowsElevation, the property names platform packages generate in other parts of the class. An action's Name cannot be one of them.

The class name and namespace defaults are set when the package's targets are evaluated, after the project file, so a project's own RootNamespace applies and platform targets can read the final values.

A platform package extends the generation with a target that depends on RunicValidatePrivilegedActions, which validates the items once, and appends that target to RunicPrivilegedActionsDependsOn; RunicGeneratePrivilegedActions writes the class only after those targets succeeded. A platform package that generates its own part of the class uses a reserved property name, and adds any new one to RunicPrivilegedActionsReservedNames.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on Runic.Platform:

Package Downloads
Runic.Platform.Runtime

Single instance, requests to open files and URLs, and file transfers for Runic applications, and the contract for native platform providers.

Runic.Desktop

A managed .NET runtime for web-powered desktop applications.

Runic.Platform.Linux.DBus

D-Bus client and service API for Runic applications on Linux: connections, typed values, proxies, exported objects, signals and properties.

Runic.Application.Views.CsWebUi

CS-WebUI host adapter for Runic Window and View applications.

Runic.Platform.Linux.Polkit

Declared privileged actions for Runic applications on Linux: a generated Polkit policy and pkexec.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.12.0 0 10/27/2026
0.11.0 3,427 10/25/2026
0.10.0 6,794 10/22/2026
0.9.1 1,075 10/21/2026
0.9.0 287 10/21/2026
0.8.0-preview.6 1,665 10/19/2026
0.8.0-preview.5 484 10/17/2026
0.8.0-preview.4 1,045 10/17/2026
0.8.0-preview.3 924 10/15/2026
0.8.0-preview.2 180 10/15/2026
0.8.0-preview.1 232 10/15/2026
0.7.0-preview.9 619 10/14/2026
0.7.0-preview.8 144 10/12/2026
0.7.0-preview.7 90 10/12/2026
0.7.0-preview.6 1,255 10/9/2026
0.7.0-preview.5 207 10/9/2026
0.7.0-preview.4 114 10/8/2026
0.7.0-preview.3 256 10/8/2026
0.7.0-preview.2 108 10/7/2026
0.7.0-preview.1 606 10/7/2026
Loading failed