package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/kardianos/service"
)
var logger service.Logger
type program struct {
isExit chan struct{}
}
func (p *program) runApp() {
ticker := time.NewTicker(time.Second * 3)
for {
select {
case <-ticker.C:
logger.Info("服务运行中......")
case <-p.isExit:
logger.Info("服务即将停止!")
ticker.Stop()
return
}
}
}
func (p *program) Start(s service.Service) error {
if service.Interactive() {
logger.Info("程序开始!")
} else {
logger.Info("服务开始!")
}
p.isExit = make(chan struct{})
go p.runApp()
return nil
}
func (p *program) Stop(s service.Service) error {
logger.Info("服务停止!")
close(p.isExit)
return nil
}
func init() {
file, _ := exec.LookPath(os.Args[0])
path, _ := filepath.Abs(file)
index := strings.LastIndex(path, string(os.PathSeparator))
runPath := path[:index]
os.Chdir(runPath)
}
func main() {
options := make(service.KeyValue)
options["OnFailure"] = "restart" // 失败后重启服务
options["OnFailureDelayDuration"] = "3s"
svcConfig := &service.Config{
Name: "go_service_demo",
DisplayName: "go service demo",
Description: "go windows服务演示",
Arguments: []string{"service"},
Option: options,
}
prg := &program{}
s, err := service.New(prg, svcConfig)
if err != nil {
fmt.Printf("service new failed! %s\r\n", err.Error())
return
}
errs := make(chan error, 5)
logger, err = s.Logger(errs)
if err != nil {
fmt.Printf("service Logger failed! %s\r\n", err.Error())
return
}
if len(os.Args) > 1 && os.Args[1] == "service" {
s.Run()
} else {
inputNum := 0
isFirst := true
for {
if !isFirst {
fmt.Println("请按回车键继续...")
var str string
fmt.Scanln(&str)
cmd := exec.Command("cmd.exe", "/c", "cls")
cmd.Stdout = os.Stdout
cmd.Run()
}
isFirst = false
serviceStatus, _ := s.Status()
if serviceStatus == service.StatusUnknown {
inputNum = showMenu(svcConfig, "未安装", "安装服务", "直接运行(非服务)", "退出程序")
switch inputNum {
case 1:
if err = s.Install(); err == nil {
fmt.Println("安装服务成功!")
} else {
fmt.Println("安装服务失败!", err)
}
case 2:
s.Run()
return
case 3:
return
}
} else if serviceStatus == service.StatusRunning {
inputNum = showMenu(svcConfig, "正在运行", "停止服务", "退出程序")
switch inputNum {
case 1:
if err = s.Stop(); err == nil {
fmt.Println("停止服务成功!")
} else {
fmt.Println("停止服务失败!", err)
}
case 2:
return
}
} else if serviceStatus == service.StatusStopped {
inputNum = showMenu(svcConfig, "未启动", "启动服务", "删除服务", "退出程序")
switch inputNum {
case 1:
if err = s.Start(); err == nil {
fmt.Println("启动服务成功!")
} else {
fmt.Println("启动服务失败!", err)
}
case 2:
if err = s.Uninstall(); err == nil {
fmt.Println("删除服务成功!")
} else {
fmt.Println("删除服务失败!", err)
}
case 3:
return
}
} else {
return
}
}
}
}
func showMenu(srvName *service.Config, srvStatus string, tips ...string) (inputNum int) {
fmt.Printf("=======================================\r\n\r\n")
fmt.Printf("\t服务名称:%s\r\n", srvName.Name)
fmt.Printf("\t服务介绍:%s\r\n", srvName.Description)
fmt.Printf("\t服务状态:%s\r\n", srvStatus)
fmt.Println("")
index := 1
for _, v := range tips {
fmt.Printf("\t%d.%s\r\n", index, v)
index++
}
fmt.Printf("\r\n=======================================\r\n")
fmt.Print("请输入:")
fmt.Scanln(&inputNum)
return
}