PhotinoX.App 5.2.1

Prefix Reserved
dotnet add package PhotinoX.App --version 5.2.1
                    
NuGet\Install-Package PhotinoX.App -Version 5.2.1
                    
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="PhotinoX.App" Version="5.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PhotinoX.App" Version="5.2.1" />
                    
Directory.Packages.props
<PackageReference Include="PhotinoX.App" />
                    
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 PhotinoX.App --version 5.2.1
                    
#r "nuget: PhotinoX.App, 5.2.1"
                    
#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 PhotinoX.App@5.2.1
                    
#: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=PhotinoX.App&version=5.2.1
                    
Install as a Cake Addin
#tool nuget:?package=PhotinoX.App&version=5.2.1
                    
Install as a Cake Tool

PhotinoX Logo

PhotinoX.App

NuGet Version Build License NuGet Downloads

Application builder, dependency injection, configuration, logging, environment, and window settings APIs for PhotinoX desktop applications.

PhotinoX provides the low-level native-first application, dispatcher, and window API. PhotinoX.App adds the application composition layer around it: services, configuration, logging, environment paths, initialization services, and reusable window settings.

PhotinoX.App also provides the application composition and lifetime foundation used by PhotinoX.Blazor.

Package architecture

PhotinoX.Native
└── PhotinoX
    └── PhotinoX.App
        └── PhotinoX.Blazor

Each layer builds on the previous one:

  • PhotinoX.Native provides the native window and WebView runtime.
  • PhotinoX exposes the managed application, dispatcher, and window APIs.
  • PhotinoX.App adds application composition, configuration, services, and lifetime management.
  • PhotinoX.Blazor adds Blazor application and window hosting.

Features

  • Service registration through IServiceCollection
  • Configuration through ConfigurationManager
  • Logging through ILoggingBuilder
  • Application environment through PhotinoEnvironment
  • Main-window factory support
  • Underlying PhotinoApplication configuration
  • Application initialization services
  • Bindable PhotinoX settings from configuration
  • Default and named window configuration
  • Callbacks before application services are disposed
  • Synchronous and asynchronous application disposal
  • Native AOT-friendly configuration binding

Quick start

Configuration can be provided from appsettings.json, environment variables, command-line arguments, or directly through the builder:

var builder = PhotinoApp.CreateBuilder(args);

builder.Configuration["PhotinoX:WebRootPath"] = "wwwroot";
builder.Configuration["PhotinoX:MainWindow:Window:Title"] = "PhotinoX.App";
builder.Configuration["PhotinoX:MainWindow:Window:Width"] = "900";
builder.Configuration["PhotinoX:MainWindow:Window:Height"] = "600";
builder.Configuration["PhotinoX:MainWindow:Window:StartUrl"] = "index.html";

builder.UseMainWindow(app =>
{
    return new PhotinoWindow()
        .ApplySettings(app.GetMainWindowConfiguration(), app.Environment);
});

using var app = builder.Build();
return app.Run();

Build() creates the application and its root service provider. Run() only runs the native application message loop and does not dispose the application. The caller must dispose the built application by using using, await using, Dispose(), or DisposeAsync().

Application builder

PhotinoAppBuilder is the main composition object.

It provides:

  • Services
  • Configuration
  • Environment
  • Logging
  • ConfigureApplication(...)
  • ConfigureBeforeDispose(...)
  • ConfigureContainer(...)
  • UseMainWindow(...)
  • UseAppServicesInitialization(...)

The builder configures services, the underlying PhotinoApplication, the main-window factory, application initialization, pre-disposal callbacks, and custom service-provider creation.

Example using the appsettings.json configuration shown below:

var builder = PhotinoApp.CreateBuilder(args);

builder.ConfigureApplication(application =>
{
    application.ShutdownMode = PhotinoShutdownMode.OnMainWindowClose;

    application.ShutdownRequested += (_, e) =>
    {
        if (e.Reason == PhotinoShutdownRequestReason.Application)
        {
            // e.Cancel = true;
        }
    };
});

builder.UseMainWindow(app =>
{
    return new PhotinoWindow()
        .ApplySettings(app.GetMainWindowConfiguration(), app.Environment);
});

using var app = builder.Build();
return app.Run();

Application lifetime

PhotinoApp.Run() runs the native application message loop. It does not dispose the application when the message loop exits.

Use synchronous disposal:

using var app = builder.Build();
return app.Run();

Use asynchronous disposal when the application or registered services require asynchronous cleanup:

await using var app = builder.Build();
return app.Run();

Code that needs to run before application services are disposed can be registered through the builder:

builder.ConfigureBeforeDispose(app =>
{
    var service = app.Services.GetRequiredService<MyService>();
    service.SaveState();
});

Callbacks are invoked in registration order. Application services remain available while callbacks execute. If a callback throws, subsequent callbacks are not invoked, but the root service provider is still disposed.

Configuration

PhotinoApp.CreateBuilder(args) creates a builder with common defaults:

  • appsettings.json
  • appsettings.{EnvironmentName}.json
  • environment variables
  • command-line arguments
  • PhotinoAppSettings binding from the PhotinoX section
  • console logging
  • IConfiguration registration
  • PhotinoEnvironment registration

The default configuration section is:

PhotinoX

appsettings.json

{
  "PhotinoX": {
    "ApplicationName": "PhotinoX App",
    "WebRootPath": "wwwroot",

    "WindowDefaults": {
      "Window": {
        "Width": 900,
        "Height": 600,
        "CenterOnInitialize": true,
        "Resizable": true
      },
      "Browser": {
        "DevToolsEnabled": true,
        "ContextMenuEnabled": true
      }
    },

    "MainWindow": {
      "Window": {
        "Title": "PhotinoX App",
        "StartUrl": "index.html"
      }
    },

    "Windows": {
      "Settings": {
        "Window": {
          "Title": "Settings",
          "Width": 700,
          "Height": 500,
          "StartUrl": "settings.html"
        }
      }
    },

    "Runtime": {
      "WebView2RuntimePath": null
    }
  }
}

The PhotinoX configuration section is bound to PhotinoAppSettings and uses this shape:

PhotinoX
├── ApplicationName
├── ContentRootPath
├── WebRootPath
├── NotificationsEnabled
├── NotificationRegistrationId
├── Runtime
├── WindowDefaults
├── MainWindow
└── Windows[name]

Window configuration

Window configuration uses a default plus override model.

For the main window:

WindowDefaults + MainWindow

For a named window:

WindowDefaults + Windows[name]

Get the effective main window configuration:

var configuration = app.GetMainWindowConfiguration();

Get a named window configuration:

var configuration = app.GetWindowConfiguration("Settings");

Apply a full window configuration:

var window = new PhotinoWindow().ApplySettings(configuration, app.Environment);

Linux chromeless window settings can be configured for default, main, and named windows:

{
  "PhotinoX": {
    "MainWindow": {
      "Linux": {
        "ChromelessDragRegionHeight": 44,
        "ChromelessDragRegionLeftInset": 0,
        "ChromelessDragRegionTopInset": 0,
        "ChromelessDragRegionRightInset": 120,
        "ChromelessResizeBorderThickness": 8
      }
    }
  }
}

These settings configure the initial Linux chromeless drag region and resize border before native window initialization. Dynamic drag and no-drag regions can be configured after initialization through the underlying PhotinoWindow API.

Environment

PhotinoEnvironment exposes EnvironmentName, ApplicationName, ContentRootPath, and WebRootPath.

Relative startup URLs can be resolved against WebRootPath:

var resolved = app.Environment.ResolveStartUrl("index.html");

Runtime settings

PhotinoRuntimeSettings contains runtime-level settings that are not per-window.

{
  "PhotinoX": {
    "Runtime": {
      "WebView2RuntimePath": "runtimes/webview2"
    }
  }
}

WebView2RuntimePath is a Windows-only application-level setting for WebView2 fixed-version deployment. It is applied before application configuration callbacks and before windows are created.

Application initialization services

IPhotinoInitializeService can be used for services that need access to the built root service provider before the application starts running.

public sealed class MyInitializer : IPhotinoInitializeService
{
    public void Initialize(IServiceProvider services)
    {
        var logger = services.GetRequiredService<ILogger<MyInitializer>>();
        logger.LogInformation("Application initialized.");
    }
}

Register it:

builder.ConfigureServices(services =>
{
    services.AddSingleton<IPhotinoInitializeService, MyInitializer>();
});

By default, initialization services run during PhotinoAppBuilder.Build().

Automatic initialization can be disabled:

var builder = PhotinoApp.CreateBuilder(new PhotinoAppOptions
{
    Args = args,
    InitializeAppServices = false
});

// Equivalent:
// var builder = PhotinoApp.CreateBuilder(args)
//     .UseAppServicesInitialization(false);

using var app = builder.Build();

app.InitializeAppServices();

return app.Run();

Services and logging

PhotinoX.App uses Microsoft.Extensions.DependencyInjection.

builder.ConfigureServices(services =>
{
    services.AddSingleton<MyService>();
    services.AddSingleton<IPhotinoInitializeService, MyInitializer>();
});

The built app exposes the root service provider:

using var app = builder.Build();

var service = app.Services.GetRequiredService<MyService>();

Default builder configuration enables console logging and reads settings from the Logging configuration section.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning"
    }
  }
}

Additional logging configuration can be applied through the builder:

builder.Logging.AddFilter("MyApp", LogLevel.Debug);

Custom service-provider creation can be configured with ConfigureContainer(...).

builder.ConfigureContainer(factory, container =>
{
    // Configure container-specific builder.
});

Ecosystem

PhotinoX.App does not replace the PhotinoX API. PhotinoApplication owns the native desktop lifetime, dispatcher, windows, and message loop. PhotinoX.App adds a lightweight application composition layer around it.

Use PhotinoX directly for minimal or fully manual applications. Use PhotinoX.App when the app needs a modern .NET-style startup model on top of PhotinoX.


Install

dotnet add package PhotinoX.App

PhotinoX.App depends on PhotinoX, which provides the managed API over the native WebView host.

Package targets net8.0; net9.0; net10.0.

Samples

Requirements

Build from source

dotnet restore src/PhotinoX.App/PhotinoX.App.csproj
dotnet build   src/PhotinoX.App/PhotinoX.App.csproj -c Release
dotnet pack    src/PhotinoX.App/PhotinoX.App.csproj -c Release -o artifacts

CI: see .github/workflows/build.yml (build + pack + upload .nupkg/.snupkg).

Contributing

Issues and PRs are welcome. Keep PRs focused, minimal, and consistent with the rest of PhotinoX.

License

PhotinoX.App is licensed under Apache-2.0.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on PhotinoX.App:

Package Downloads
PhotinoX.Blazor

Blazor integration for PhotinoX (.NET wrapper for OS-native WebView windows). Maintained fork of Photino.Blazor.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.2.1 0 9/18/2026
5.2.0 140 9/16/2026
5.1.2 850 8/25/2026
5.1.1 213 8/23/2026
5.1.0 161 8/21/2026
5.0.3 119 8/17/2026
5.0.2 111 8/17/2026
5.0.1 107 8/15/2026
5.0.0 109 8/12/2026
5.0.0-preview.2 71 8/12/2026
5.0.0-preview.1 67 8/7/2026