[TOC]
1 背景
自己开发了一个应用程序,想要再windows
上后台运行,并且能够设置为开机启动。
2 目标
可以在Windows
上配置任意一个可执行文件后台启动,并且设置为开机启动。
3 应用程序测试代码
测试代码非常简单,就是再运行之后,每隔三秒钟在可执行文件的同级目录的app-logs文件夹中创建文件。如果程序正常运行,那么我们就可以看到新创建的文件。
编译命令:go build -o app.exe main.go
package main
import (
"fmt"
"os"
"time"
)
func main() {
dir := "app-logs"
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
fmt.Printf("%s\n", err)
os.Exit(1)
}
for {
file := fmt.Sprintf(".\\%s\\app测试_%s.txt", dir, time.Now().Format("2006.01.02_15_04_05"))
_, err := os.Create(file)
if err != nil {
os.Exit(1)
}
time.Sleep(3 * time.Second)
}
}
4 解决方案
4.1 方案一 使用sc命令注册服务(不推荐)
4.1.1 相关命令
⚠注意:这些命令的执行需要以管理员的方式打开CMD
注册服务:sc create ceshi binpath= D:\Project\ceshi\app.exe type= own start= auto displayname= ceshi
,注意等号后面的空格
删除服务:sc delete ceshi
启动服务:sc start ceshi
查看服务:sc query ceshi
4.1.2 测试过程
测试日志如下
C:\Windows\system32>
C:\Windows\system32>
C:\Windows\system32>sc create ceshi binpath= D:\Project\ceshi\app.exe type= own start= auto displayname= ceshi
[SC] CreateService 成功
C:\Windows\system32>sc query ceshi
SERVICE_NAME: ceshi
TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 1077 (0x435)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
C:\Windows\system32>sc start ceshi
[SC] StartService 失败 1053:
服务没有及时响应启动或控制请求。
C:\Windows\system32>
C:\Windows\system32>sc query ceshi
SERVICE_NAME: ceshi
TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
C:\Windows\system32>
4.1.3 弊端
这种方式注册的服务需要符合一定的规范,否则服务即使能够成功,启动服务时也极有可能报错
4.2 方案二 使用WinSW包装应用程序为服务
4.2.1 步骤
第一步:下载WinSW
软件:github下载链接
第二步:把WinSW
复制到需要启动应用的目录位置,然后重命名,譬如我这里重命名为app-server.exe
。重命名的目的是为了后面书写命令更加方便
第三步:在目录中新建和第二步同名的yml
配置文件,譬如我这里就是app-server.xml
当然也可以使用XML
语法配置文件,WinSW
都支持。YAML配置参考链接,XML配置参考链接
# 服务ID名称(唯一)
id: App-Server
# 服务显示名称
name: App-Server
# 服务的描述信息
description: 测试APP应用程序
# 环境变量设置
env:
- name: "HOME"
value: "%BASE%"
# 要执行的可执行文件
executable: "%BASE%/app.exe"
# 可执行文件传递的参数
# server: '%BASE%\data'
log:
mode: roll-by-size
logpath: "%BASE/log%"
sizeThreshold: 10240
keepFiles: 8
⚠注意:这里XML
配置文件的名字必须和WinSW
文件名相同,因为WinSW
启动之后会去寻找同名的配置文件
当前环境如下:
PS D:\Project\ceshi> ls
目录: D:\Project\ceshi
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2024-03-19 21:59 18243033 app-server.exe
-a---- 2024-03-19 22:42 859 app-server.xml
-a---- 2024-03-19 21:13 4233216 app.exe
第四步:注册服务。以管理员身份启动CMD,进入到上述目录,执行install
命令,譬如我这里为:app-server install
D:\Project\ceshi>app-server install
2024-03-19 22:58:45,521 INFO - Installing service 'App-Server (App-Server)'...
2024-03-19 22:58:45,547 INFO - Service 'App-Server (App-Server)' was installed successfully.
D:\Project\ceshi>
第五步:按下win + r
,然后输入services.msc
,打开服务页面,查看列表中是否存在前面注册的服务
第六步:启动服务。以管理员身份启动CMD,进入到上述目录,执行start
命令,譬如我这里为:app-server start
D:\Project\ceshi>app-server start
2024-03-19 23:05:24,026 INFO - Starting service 'App-Server (App-Server)'...
2024-03-19 23:05:24,341 INFO - Service 'App-Server (App-Server)' started successfully.
D:\Project\ceshi>
第七步:校验服务是否真正启动,是否异常退出。只要发现文件在不同的创建,就说明当前配置没有问题。
PS D:\Project\ceshi> tree /f
卷 软件 的文件夹 PATH 列表
卷序列号为 D32A-2561
D:.
│ app-server.exe
│ app-server.xml
│ app.exe
│
├─app-logs
│ app测试_2024.03.20_07_31_30.txt
│ app测试_2024.03.20_07_31_33.txt
│ app测试_2024.03.20_07_31_36.txt
│ app测试_2024.03.20_07_31_39.txt
│ app测试_2024.03.20_07_31_42.txt
│ app测试_2024.03.20_07_31_45.txt
│
└─logs
app-server.err.log
app-server.out.log
app-server.wrapper.log
第八步:查看服务状态。以管理员身份启动CMD,进入到上述目录,执行status
命令,譬如我这里为:app-server status
D:\Project\ceshi>app-server status
Started
D:\Project\ceshi>
4.2.2 WinSW命令说明
install:注册服务
uninstall:卸载服务
start:启动服务,启动服务之前,该服务必须已经安装
stop:停止服务
stopwait:停止服务,直到服务退出,此命令才返回
restart:重启服务
status:查看服务状态