go注册Windows服务

做一个极简的服务

新建

新建test1.go

package main

import (
	"time"
	"log"
	"os"
	"github.com/kardianos/service"
)
//var state bool
type program struct{}

func (p *program) Start(s service.Service) error {
	//state = true
	log.Println("start")
	go p.run()
	return nil
}

func (p *program) run() {
	for{
		/*if !state{
			log.Println("end run!")
			break
		}*/
		log.Println("running...")
		time.Sleep(time.Duration(1)*time.Second)
	}
}

func (p *program) Stop(s service.Service) error {
	//state = false
	log.Println("end")
	return nil
}

/**
 * MAIN函数,程序入口
 */
func main() {
	logFile, err := os.OpenFile("C:\\Users\\14784\\Desktop\\service.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
	if err != nil {
		panic(err)
	}
	log.SetOutput(logFile) // 将文件设置为log输出的文件

	svcConfig := &service.Config{
		Name:        "test_service", //服务显示名称
		DisplayName: "service test", //服务名称
		Description: "go service test", //服务描述
	}

	prg := &program{}
	s, err := service.New(prg, svcConfig)
	if err != nil {
		log.Fatal(err)
	}


	if len(os.Args) > 1 {
		if os.Args[1] == "install" {
			err = s.Install()
			if err != nil {
				log.Fatal(err)
			}
			log.Println("服务安装成功")
			return
		}

		if os.Args[1] == "uninstall" {
			err=s.Uninstall()
			if err != nil {
				log.Fatal(err)
			}
			log.Println("服务卸载成功")
			return
		}
	}
	err = s.Run()
	if err != nil {
		log.Fatal(err)
	}
}
  • 函数start再服务开始的时候被调用
  • 函数stop再服务停止的时候被调用
  • 函数run是服务运行时一直运行

运行

注:安装卸载要用管理员权限运行

创建mod文件

go mod init service_test

编译

go build test1.go 

安装

test1.exe install

卸载

test1.exe uninstall

测试

右键test_service开始,运行一段时间后点停止

80

测试发现即使stop不做任何处理,run也会被系统停止

将exe封装成一个服务

新建一个demo

新建demo.go

package main

import (
	"log"
	"os"
	"time"
)

func main() {

	logFile, err := os.OpenFile("C:\\Users\\14784\\Desktop\\demo.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
	if err != nil {
		panic(err)
	}
	log.SetOutput(logFile) // 将文件设置为log输出的文件

	for{
		log.Println("running...")
		time.Sleep(time.Duration(1)*time.Second)
	}
}

编译

go build demo.go

新建test2.go

package main

import (
	"context"
	"os/exec"

	"log"
	"os"
	"github.com/kardianos/service"
)
var state bool
type program struct{}

func (p *program) Start(s service.Service) error {
	state = true
	log.Println("start")
	go p.run()
	return nil
}

func (p *program) run() {
	ctx, cancel := context.WithCancel(context.Background())
	//cmd := exec.CommandContext(ctx,"cmd","/C","D:\\xzw\\demo\\go\\注册windows服务\\demo.exe")
	cmd := exec.CommandContext(ctx,"D:\\xzw\\demo\\go\\注册windows服务\\demo.exe")
	cmd.Start()
	log.Println("start demo")
	for{
		if state{
			continue
		}
		log.Println("cancel demo")
		cancel()
		break
	}

	cmd.Wait()
}

func (p *program) Stop(s service.Service) error {
	state = false
	log.Println("end")
	//time.Sleep(time.Duration(2)*time.Second)
	return nil
}

/**
 * MAIN函数,程序入口
 */
func main() {
	logFile, err := os.OpenFile("C:\\Users\\14784\\Desktop\\service.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
	if err != nil {
		panic(err)
	}
	log.SetOutput(logFile) // 将文件设置为log输出的文件

	svcConfig := &service.Config{
		Name:        "test_service", //服务显示名称
		DisplayName: "service test", //服务名称
		Description: "go service test", //服务描述
	}

	prg := &program{}
	s, err := service.New(prg, svcConfig)
	if err != nil {
		log.Fatal(err)
	}


	if len(os.Args) > 1 {
		if os.Args[1] == "install" {
			err = s.Install()
			if err != nil {
				log.Fatal(err)
			}
			log.Println("服务安装成功")
			return
		}

		if os.Args[1] == "uninstall" {
			err=s.Uninstall()
			if err != nil {
				log.Fatal(err)
			}
			log.Println("服务卸载成功")
			return
		}
	}
	err = s.Run()
	if err != nil {
		log.Fatal(err)
	}
}
  • 注意要填绝对路径不然服务会找不到exe

安装

test2.exe install

卸载

test2.exe uninstall

测试

点击开始之后demo就开始输出,点击停止demo就停止输出

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×