Commit 0215474
Windows: install the background service without Administrator (#1211)
* Windows: install the background service without Administrator
The Windows `executor install` / `executor service install` always required
an elevated PowerShell. It registered the daemon as a boot-triggered Scheduled
Task (AtStartup + S4U + RunLevel Highest), and Task Scheduler only lets an
Administrator create that shape. macOS (launchd RunAtLoad) and Linux
(systemd --user) both install per-user with no elevation, so Windows was the
odd one out.
Default to a per-user logon task instead: a LogonTrigger + InteractiveToken
principal at LeastPrivilege, which a standard user may register for themselves.
This matches the launchd/systemd behavior (start at login, unprivileged). The
old boot-before-login behavior is preserved behind an explicit `--boot` flag,
which still needs an Administrator shell and says so.
Register via schtasks.exe rather than the PowerShell *-ScheduledTask cmdlets.
Those cmdlets reach Task Scheduler over CIM/DCOM, whose local-activation check
fails with Access denied (0x80070005) when the compiled binary spawns the
helper on a non-interactive window station; schtasks uses Task Scheduler RPC and
has no such dependency. status/uninstall/restart and the orphaned-listener
cleanup move off CIM too (schtasks query + netstat/taskkill).
A logon task runs in the user's interactive session, so launch the daemon
through a hidden wscript shim to avoid flashing a console window on the desktop
at every login; the shim waits on the wrapper so the task stays Running and
RestartOnFailure is preserved.
Verified on Windows Server 2022 as a standard, non-admin user: `--boot` is
correctly refused, the default install registers a logon task, the daemon comes
up, and /api/health returns 200.
* Windows service: locale-invariant status + guard --boot off-Windows
Address review on non-English Windows:
- status() derived "running" from the schtasks `Status: Running` line, but
both the label and the word are localized (fr: `État : En cours d'exécution`),
so it always read as not-running on a non-English install. Detect via the
locale-invariant SCHED_S_TASK_RUNNING result code (267009 / 0x41301) instead,
extracted into the pure, tested parseSchtasksRunning().
- parseNetstatListenerPids matched the localized `LISTENING` state word. Identify
a listener by its wildcard/zero remote endpoint (0.0.0.0:0 / [::]:0) instead;
TCP and addresses are not localized.
- `--boot` is documented Windows-only but was silently ignored on macOS/Linux.
Warn when it is passed on a non-Windows platform.
Tests add fr-FR / de-DE fixtures for both parsers. Verified on the Windows guest
against a real running task's schtasks output: the old Status/Running regex
regresses to false under fr-FR rendering while the 267009-based check stays
correct.
---------
Co-authored-by: Rhys Sullivan <rhys@executor.sh>1 parent fdc0100 commit 0215474
3 files changed
Lines changed: 456 additions & 181 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2794 | 2794 | | |
2795 | 2795 | | |
2796 | 2796 | | |
| 2797 | + | |
| 2798 | + | |
| 2799 | + | |
| 2800 | + | |
| 2801 | + | |
| 2802 | + | |
| 2803 | + | |
| 2804 | + | |
| 2805 | + | |
| 2806 | + | |
2797 | 2807 | | |
2798 | 2808 | | |
2799 | 2809 | | |
| |||
2807 | 2817 | | |
2808 | 2818 | | |
2809 | 2819 | | |
2810 | | - | |
| 2820 | + | |
2811 | 2821 | | |
2812 | 2822 | | |
2813 | 2823 | | |
| |||
2822 | 2832 | | |
2823 | 2833 | | |
2824 | 2834 | | |
| 2835 | + | |
| 2836 | + | |
| 2837 | + | |
| 2838 | + | |
| 2839 | + | |
| 2840 | + | |
| 2841 | + | |
| 2842 | + | |
| 2843 | + | |
| 2844 | + | |
2825 | 2845 | | |
2826 | 2846 | | |
2827 | | - | |
| 2847 | + | |
| 2848 | + | |
| 2849 | + | |
| 2850 | + | |
| 2851 | + | |
| 2852 | + | |
2828 | 2853 | | |
2829 | 2854 | | |
2830 | 2855 | | |
| |||
2881 | 2906 | | |
2882 | 2907 | | |
2883 | 2908 | | |
2884 | | - | |
| 2909 | + | |
2885 | 2910 | | |
2886 | 2911 | | |
2887 | 2912 | | |
| |||
2904 | 2929 | | |
2905 | 2930 | | |
2906 | 2931 | | |
2907 | | - | |
| 2932 | + | |
| 2933 | + | |
| 2934 | + | |
| 2935 | + | |
| 2936 | + | |
2908 | 2937 | | |
2909 | 2938 | | |
2910 | 2939 | | |
2911 | 2940 | | |
2912 | 2941 | | |
2913 | 2942 | | |
2914 | 2943 | | |
| 2944 | + | |
2915 | 2945 | | |
2916 | | - | |
| 2946 | + | |
2917 | 2947 | | |
2918 | 2948 | | |
2919 | 2949 | | |
| |||
2996 | 3026 | | |
2997 | 3027 | | |
2998 | 3028 | | |
| 3029 | + | |
2999 | 3030 | | |
3000 | | - | |
| 3031 | + | |
3001 | 3032 | | |
3002 | 3033 | | |
3003 | 3034 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | | - | |
| 8 | + | |
| 9 | + | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
| |||
124 | 126 | | |
125 | 127 | | |
126 | 128 | | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
132 | 134 | | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
149 | 230 | | |
150 | 231 | | |
151 | 232 | | |
| |||
0 commit comments