Windows Service deployment
This guide is the self-hosted Windows Service baseline for freshly generated Cephalon apps.
Use it when you want a generated host to move from scaffolded source to deterministic published output and then into a Windows Service install shape without inventing your own sc.exe contract first.
What ships now
Section titled “What ships now”Generated app roots from cephalon new and the app-focused dotnet new cephalon-* starters now include:
Properties/PublishProfiles/CephalonFolder.pubxmldeploy/windows-service/README.mddeploy/windows-service/install-service.ps1deploy/windows-service/remove-service.ps1
The generated host also now carries Windows Service-aware startup wiring through Microsoft.Extensions.Hosting.WindowsServices, WindowsServiceHelpers.IsWindowsService(), and builder.Host.UseWindowsService().
Publish the host
Section titled “Publish the host”For scaffolded multi-project apps from cephalon new:
dotnet publish ./Acme.Store/src/Acme.Store.Host/Acme.Store.Host.csproj -p:PublishProfile=CephalonFolderFor app-starter templates from dotnet new cephalon-*:
dotnet publish ./Acme.Store.TemplateStarter/Acme.Store.TemplateStarter.csproj -p:PublishProfile=CephalonFolderInstall the published output
Section titled “Install the published output”The shipped Windows Service baseline assumes:
- published output is copied to
C:\Services\<AppName>\current dotnetis available on the Windows target- the real install or removal step is run from an elevated PowerShell session
Example for a scaffolded modular-monolith app:
New-Item -ItemType Directory -Path 'C:\Services\Acme.Store\current' -Force | Out-NullCopy-Item -Path .\Acme.Store\artifacts\publish\Acme.Store.Host\* -Destination 'C:\Services\Acme.Store\current' -Recurse -Forcepwsh ./Acme.Store/deploy/windows-service/install-service.ps1 -PublishRoot 'C:\Services\Acme.Store\current' -PreviewThe preview step prints the sc.exe create, sc.exe description, and recovery commands without requiring admin rights. When you are ready to install the service for real, rerun the same command from an elevated PowerShell session without -Preview:
pwsh ./Acme.Store/deploy/windows-service/install-service.ps1 -PublishRoot 'C:\Services\Acme.Store\current'Start-Service -Name 'Acme.Store'Get-Service -Name 'Acme.Store'sc.exe qc 'Acme.Store'The generated install script passes:
- the published DLL path under
C:\Services\<AppName>\current --contentRootpointing at that same published folder--environment Production--urls http://127.0.0.1:8080
That keeps config loading and content-root behavior deterministic when the Service Control Manager launches the process.
Remove or inspect the service
Section titled “Remove or inspect the service”To remove the service later:
pwsh ./Acme.Store/deploy/windows-service/remove-service.ps1cephalon doctor --app-root ./Acme.Store now also validates that deploy/windows-service/remove-service.ps1 keeps the generated Get-Service, Stop-Service, and sc.exe delete teardown flow explicit before teams rely on that removal path.
Once the service is running, inspect:
/engine/engine/snapshot/engine/runtime-story/health/health/ready/scalar
If you need host-level startup details, inspect the Windows Service state with Get-Service, sc.exe qc, and the Windows Event Viewer / Application log for process-start failures.
Optional repo-native validation script
Section titled “Optional repo-native validation script”To replay the generated Windows Service baseline from the Cephalon repository in one command, run:
pwsh ./scripts/validate-generated-app-windows-service.ps1That script:
- scaffolds a fresh app through
Cephalon.Cli - seeds
./.cephalon/packageswith repo-local package artifacts - publishes the generated host through
CephalonFolder.pubxml - verifies that the generated host is wired for Windows Service startup
- replays the shipped install/remove scripts in preview mode against the published output
- tears the temporary app back down afterward unless
-KeepOutputis supplied