中文 English

Windows 11/10 后台服务开机自启:把 frp、EasyTier 变成真正无人值守的后台任务

发布时间: 2026-06-27
开机自启 后台服务 frp EasyTier 自动化 Agent 运维 Windows 11/10

先说结论

如果你要让 frpEasyTier、同步器、采集器、机器人、代理程序这类后台服务在 Windows 11/10 上开机自动运行,核心不是“把命令藏在哪里”,而是“让系统的服务管理器负责它”。这篇文章只讨论后台常驻服务,不讨论普通桌面 App 的登录启动。

Windows 的关键判断是:程序是不是原生 Windows Service。frp、EasyTier 这类常见命令行守护进程通常更适合用计划任务在系统启动时运行,因为计划任务是系统内置能力,不需要 NSSM、WinSW 之类第三方 wrapper。

我会给出两条路:人工配置,适合你想理解每一步;Agent/一键脚本自动配置,适合你已经知道二进制和配置文件放在哪里,希望复制一段脚本直接落地。脚本不依赖第三方服务,不下载外部 wrapper,也不会写入任何真实 IP、真实主机名或私有域名。

AI 生成封面:后台服务在系统启动阶段被统一拉起。

AI 生成封面:后台服务在系统启动阶段被统一拉起。


一、问题背景:后台服务不是“我登录后顺手打开的软件”

很多家庭实验室、小公司内网、开发机和边缘节点,都会跑一些“没人看着也必须一直在”的小服务。最典型的就是 frpEasyTier、反向代理、监控采集器、文件同步器、通知机器人、定时拉取器。它们的共同特点是:界面不重要,持续运行才重要;人不登录,服务也应该起来;机器重启后,服务应该自动恢复。

很多人第一次配置时,会把命令放在终端里手敲:

/opt/frp/frpc -c /etc/frp/frpc.toml

或者写进某个用户的 shell 启动脚本。短期看似能用,但它有三个硬伤。第一,终端一关进程就可能没了;第二,机器重启后必须有人登录;第三,服务崩溃后没人负责拉起来。

打个比方:后台服务像小区的水泵,不能等业主起床下楼才打开。开机自启动的正确目标,是让它变成“楼宇基础设施”,电闸合上、网络准备好、水泵就自己转;坏了会报警或重启;关机时也按顺序停。

解释图:从开机到网络就绪再到服务常驻的生命周期。

解释图:从开机到网络就绪再到服务常驻的生命周期。

二、问题表现:为什么“能运行”不等于“能自启动”

后台服务自启动失败,表现通常不是一个大红错,而是几个很烦的小症状:

这里最容易误判的是“命令能跑”。命令能跑,只说明二进制、配置文件、网络在当前 shell 环境里大体没问题;它并不说明系统启动阶段也能找到同样的路径、权限、环境变量和网络状态。

三、问题根因:缺的不是命令,而是生命周期管理

后台服务真正需要的是完整生命周期:什么时候启动、以谁的身份启动、在哪个目录启动、依赖什么、挂了怎么办、日志写到哪里、关机时怎么停。

Windows 11/10 的标准机制是 计划任务或原生 Windows 服务。你可以把它理解成“值班经理”。我们不再让服务自己站在门口喊“我开工了”,而是告诉值班经理:这名员工叫什么、几点上班、工具在哪、出故障要不要叫回来、下班时怎么收尾。

frp / EasyTier 这类服务,最重要的判断有四个:

  1. 是否必须在用户登录前启动:后台隧道通常是必须的。
  2. 是否需要网络就绪:几乎一定需要。
  3. 是否需要 root 或管理员权限:取决于是否创建虚拟网卡、监听低端口、修改路由。
  4. 是否能被系统监督重启:长期运行的服务应该能失败重启。

真实截图 1:Microsoft sc create 文档,适合真正实现 Windows Service 接口的程序。

真实截图 1:Microsoft sc create 文档,适合真正实现 Windows Service 接口的程序。

四、人工配置:先慢一点,把关键点看懂

人工配置不是为了显得高级,而是为了让你知道自动脚本到底改了什么。建议按这四步走:

  1. 确认二进制能执行:先用绝对路径运行,避免依赖 PATH
  2. 确认配置文件存在:配置里不要写真实地址到博客或截图里,生产机器自己保留真实值即可。
  3. 写入服务定义:声明启动命令、工作目录、重启策略、日志位置。
  4. 启用并立即启动:启用代表下次开机自动启动,立即启动代表现在就验证。

frp 为例,人工配置的核心不是那一行 ExecStart,而是把“网络就绪后启动、失败后重启、用专门用户运行、日志可查”这些约束写清楚。以 EasyTier 为例,思路完全一样,只是二进制路径和参数换成 easytier-core

人工配置后,不要只看进程在不在。至少做三类验证:服务管理器看到它是 enabled;当前状态是 running 或 active;日志里没有连续失败重启。

解释图:人工配置时应该按检查、写配置、启用、验证的顺序走。

解释图:人工配置时应该按检查、写配置、启用、验证的顺序走。

五、Agent 自动配置:一句话让 Agent 做,但要给它边界

我推荐给 Agent 的一句话是:

请在当前 Windows 11/10 机器上,把指定后台程序配置为开机自启动服务。服务名使用 <SERVICE_NAME>,二进制路径使用 <BINARY_PATH>,配置文件使用 <CONFIG_PATH>。请先检查路径和权限,再写入系统服务配置,启用开机自启并立即启动,最后输出状态、日志和回滚命令。不要联网下载第三方 wrapper,不要把真实 IP、真实主机名、私有域名或密钥写入说明。

这句话的重点是“先检查,再写入,最后验证”。Agent 自动化不是许愿池,它更像一个执行力很强的实习生。你要告诉它工作边界:不下载第三方工具,不覆盖已有配置,不泄露真实地址,不跳过验证。

解释图:Agent 自动配置不是魔法,本质是把检查和写配置脚本化。

解释图:Agent 自动配置不是魔法,本质是把检查和写配置脚本化。

下面是一键脚本模板。你只需要改环境变量里的服务名、二进制路径、配置路径和参数。它的设计目标是:可重复执行、失败时尽早退出、最后给出状态证据

# Run in an elevated PowerShell window.
# Usage:
#   $env:SERVICE_NAME="frpc"
#   $env:BINARY_PATH="C:\Tools\frp\frpc.exe"
#   $env:WORK_DIR="C:\Tools\frp"
#   $env:APP_ARGS="-c C:\ProgramData\frp\frpc.toml"
#   .\Install-StartupTask.ps1

$ErrorActionPreference = "Stop"

$ServiceName = if ($env:SERVICE_NAME) { $env:SERVICE_NAME } else { "frpc" }
$BinaryPath = if ($env:BINARY_PATH) { $env:BINARY_PATH } else { "C:\Tools\frp\frpc.exe" }
$WorkDir = if ($env:WORK_DIR) { $env:WORK_DIR } else { Split-Path -Parent $BinaryPath }
$AppArgs = if ($env:APP_ARGS) { $env:APP_ARGS } else { "-c C:\ProgramData\frp\frpc.toml" }
$TaskPath = "\"
$TaskName = "$ServiceName-autostart"

if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
  throw "Please run PowerShell as Administrator."
}
if (-not (Test-Path $BinaryPath)) {
  throw "Binary not found: $BinaryPath"
}
if (-not (Test-Path $WorkDir)) {
  throw "Working directory not found: $WorkDir"
}

$Action = New-ScheduledTaskAction -Execute $BinaryPath -Argument $AppArgs -WorkingDirectory $WorkDir
$Trigger = New-ScheduledTaskTrigger -AtStartup
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
$Settings = New-ScheduledTaskSettingsSet `
  -StartWhenAvailable `
  -RestartCount 999 `
  -RestartInterval (New-TimeSpan -Minutes 1) `
  -ExecutionTimeLimit (New-TimeSpan -Seconds 0) `
  -MultipleInstances IgnoreNew

Register-ScheduledTask -TaskPath $TaskPath -TaskName $TaskName -Action $Action -Trigger $Trigger -Principal $Principal -Settings $Settings -Force | Out-Null
Start-ScheduledTask -TaskPath $TaskPath -TaskName $TaskName
Start-Sleep -Seconds 2
Get-ScheduledTask -TaskPath $TaskPath -TaskName $TaskName | Format-List TaskName,State
Get-ScheduledTaskInfo -TaskPath $TaskPath -TaskName $TaskName | Format-List LastRunTime,LastTaskResult,NextRunTime

真实截图 2:Microsoft schtasks create 文档,适合普通控制台后台程序开机启动。

真实截图 2:Microsoft schtasks create 文档,适合普通控制台后台程序开机启动。

六、frp / EasyTier 的套用方式

frp 的典型套用方式是:服务名叫 frpc,二进制在 /opt/frp/frpc 或你的工具目录,配置文件在 /etc/frp/frpc.toml。脚本会把它包装成系统后台服务,开机时自动拉起。

EasyTier 的典型套用方式是:服务名叫 easytier,二进制是 easytier-core,参数使用 --config-file <CONFIG_PATH>。如果你的 EasyTier 需要创建虚拟网卡或修改路由,就要确认运行身份有足够权限。

这两者的本质没有区别:一个是“反向连接的隧道工”,一个是“组网的道路工”。你要做的是给它们发一张长期工牌,而不是每天早上手动叫它们上班。

七、验证清单:不要相信“应该可以”

配置完成后,按下面顺序验证:

验证就像收快递签字。你不能只看快递员说“送到了”,你要打开门看包裹真的在门口。

八、常见坑位

坑 1:相对路径。 手动运行时当前目录正确,开机时当前目录不一定正确。后台服务统一使用绝对路径。

坑 2:依赖用户登录。 登录项、shell profile、终端窗口都不是可靠后台服务方案。

坑 3:网络还没准备好。 隧道服务通常依赖网络,启动过早会失败。要让服务管理器知道它需要网络。

坑 4:把密钥写进命令行。 命令行参数可能被进程列表看到。密钥优先放进权限受控的配置文件。

坑 5:没有重启策略。 后台服务不怕偶发失败,怕的是失败后没人知道、没人拉起。

解释图:自启动失败时,按权限、路径、网络、日志四条线排查。

解释图:自启动失败时,按权限、路径、网络、日志四条线排查。

九、回滚方式

回滚也要脚本化。思路很简单:停止服务、禁用开机自启、删除服务定义、重新加载服务管理器。不要直接删除二进制和配置文件,除非你确认它们不再被别的服务使用。

如果你把自启动理解成“给服务办入职”,回滚就是“办离职”。离职要交回门禁卡,但不一定要把办公桌一起砸了。

十、Q&A

Q:能不能继续用 tmux、screen、nohup?

可以临时用,但不建议当长期方案。它们更像临时帐篷,适合调试,不适合当房子。

Q:一键脚本是不是一定安全?

不是。一键脚本的安全性来自可读、可审计、可回滚。复制前先看变量和写入路径。

Q:为什么不用第三方服务 wrapper?

不是不能用,而是这篇文章的目标是“系统原生能力优先”。少一个外部依赖,就少一个升级和供应链风险。

Q:配置里必须出现真实服务器地址怎么办?

生产配置当然需要真实地址,但文章、截图、提交记录里不要出现。可以在本机保留真实配置,分享时使用 <SERVER_ENDPOINT> 这类占位符。

真实截图 3:PowerShell New-Service 文档,说明原生服务的创建方式。

真实截图 3:PowerShell New-Service 文档,说明原生服务的创建方式。

参考资料