之前使用了 winsw/winsw 来注册程序到windows服务
后来某项目使用了windows server 2008, 刚好因为winsw
WinSW 3 can run on Windows platforms with .NET Framework 4.6.1
or later versions installed. For systems without .NET Framework, the project provides native 64-bit and 32-bit executables based on .NET 7.
直接报错。
找到项目 kardianos/service, 是基于golang开发的,结构简单,适合二次开发。
程序需要实现接口
type Interface interface {
// Start provides a place to initiate the service. The service doesn't
// signal a completed start until after this function returns, so the
// Start function must not take more then a few seconds at most.
Start(s Service) error
// Stop provides a place to clean up program execution before it is terminated.
// It should not take more then a few seconds to execute.
// Stop should not call os.Exit directly in the function.
Stop(s Service) error
}
要注意的是需要在Start接口内异步操作业务,直接go关键字跑一下就好了。
然后就可以新建配置并创建服务
svcConfig := &service.Config{
Name: config.Name,
DisplayName: config.Name,
Description: config.Description,
}
s, err := service.New(prg, svcConfig)
if err != nil {
log.Fatal(err)
}
prg
是接口Interface
的实现
其中service.Config
的参数有很多, 比如Executable等。 其中我们需要通过读取配置文件的方式来获取到程序需要的参数。
比如:Start函数响应时要执行的命令和参数、日志的路径、服务注册时需要的名称、描述等。
最后判断下参数,看是传递service还是直接跑就行了
if len(*svcFlag) != 0 {
log.Println("scvFlag: ", *svcFlag)
err := service.Control(s, *svcFlag)
if err != nil {
log.Printf("Valid actions: %q\n", service.ControlAction)
log.Fatal(err)
}
return
}
err = s.Run()
if err != nil {
logger.Error(err)
}
注册到服务后,工作路径是系统目录,需要程序切换到正确的工作路径。
先是找到程序本身的位置
fullexecpath, err := os.Executable()
if err != nil {
panic(err.Error())
}
dir, _ := filepath.Split(fullexecpath)
os.Chdir(dir)