A LocalSystem Windows service can't see the logged-in user's Claude CLI authentication, so the worker now runs as the current user via a hidden per-user logon Scheduled Task with restart-on-failure. - Worker is WinExe (no console window) with a Serilog rolling file sink and a single-instance mutex so the logon task, app ensure-running, and Restart button can't fight over the SignalR port. - Installer replaces the service steps (register/start/stop) with autostart task steps, migrates the legacy ClaudeDoWorker service away on update, and removes the task on uninstall. ServicePage drops the service-account UI. - UI gains a WorkerLocator; the app ensures the worker is running at startup and the Restart button kills+relaunches this install's worker process. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
31 lines
1.1 KiB
C#
31 lines
1.1 KiB
C#
using ClaudeDo.Installer.Core;
|
|
|
|
namespace ClaudeDo.Installer.Tests;
|
|
|
|
public class ScheduledTaskXmlTests
|
|
{
|
|
[Fact]
|
|
public void Build_EmbedsUserExeAndLogonTrigger()
|
|
{
|
|
var xml = ScheduledTaskXml.Build(
|
|
userId: "MACHINE\\mika",
|
|
workerExePath: @"C:\Program Files\ClaudeDo\worker\ClaudeDo.Worker.exe",
|
|
restartIntervalMinutes: 1);
|
|
|
|
Assert.Contains("<LogonTrigger>", xml);
|
|
Assert.Contains("<UserId>MACHINE\\mika</UserId>", xml);
|
|
Assert.Contains("<LogonType>InteractiveToken</LogonType>", xml);
|
|
Assert.Contains("<Hidden>true</Hidden>", xml);
|
|
Assert.Contains("<RunLevel>LeastPrivilege</RunLevel>", xml);
|
|
Assert.Contains(@"C:\Program Files\ClaudeDo\worker\ClaudeDo.Worker.exe", xml);
|
|
Assert.Contains("<Interval>PT1M</Interval>", xml);
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_ClampsRestartIntervalToOneMinuteMinimum()
|
|
{
|
|
var xml = ScheduledTaskXml.Build("M\\u", @"C:\w.exe", restartIntervalMinutes: 0);
|
|
Assert.Contains("<Interval>PT1M</Interval>", xml);
|
|
}
|
|
}
|