golang

golang windows service

kimbs0301 2025. 1. 5. 11:19

golang.org/x/sys/windows/svc 패키지 사용으로 윈도우 서비스 등록 및 실행

 

go get 사용으로 패키지 추가

> go get golang.org/x/sys/windows/svc

 

프로젝트 디렉토리 생성

> mkdir C:\\workspace\\myGoService

> mkdir C:\\workspace\\myGoService\\logs

 

main.go

// Package main
package main

import (
	"fmt"
	"os"
	"runtime"
	"time"

	"golang.org/x/sys/windows/svc"
	"golang.org/x/sys/windows/svc/debug"
)

// init
func init() {
	runtime.GOMAXPROCS(runtime.NumCPU()) // CPU 코어 개수 만큼 프로세스 설정
}

// main
func main() {
	if len(os.Args) == 2 && os.Args[1] == "liveMode" {
		err := svc.Run("MyGoService", &myGoService{})
		if err != nil {
			panic(err)
		}
	} else { // 콘솔 출력 디버깅
		fmt.Println("debugMode")
		err := debug.Run("MyGoService", &myGoService{})
		if err != nil {
			panic(err)
		}
	}
}

// myGoService
type myGoService struct {
	// 서비스 Type
}

// Execute
func (srv *myGoService) Execute(args []string, req <-chan svc.ChangeRequest, stat chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) {
	// svc.Handler 인터페이스 구현
	stat <- svc.Status{State: svc.StartPending}

	// 동작 서비스
	stopChan := make(chan bool, 1)
	go myExecute(stopChan)

	stat <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}

LOOP_LABEL:
	for {
		// 서비스 변경 요청에 대해 핸들링
		switch r := <-req; r.Cmd {
		case svc.Stop, svc.Shutdown:
			stopChan <- true
			break LOOP_LABEL

		case svc.Interrogate:
			stat <- r.CurrentStatus
			time.Sleep(100 * time.Millisecond)
			stat <- r.CurrentStatus

			//case svc.Pause:
			//case svc.Continue:
		}
	}

	stat <- svc.Status{State: svc.StopPending}
	return
}

// myExecute
func myExecute(stopChan chan bool) {
	for {
		select {
		case <-stopChan:
			return
		default:
			time.Sleep(3 * time.Second)
			os.WriteFile("C:/workspace/myGoService/logs/log.txt", []byte(time.Now().UTC().String()), 0)
		}
	}
}

 

3초마다 log.txt 파일에 현재 시간을 기록하는 윈도우 서비스 프로그램이다.

 

빌드

> go build -o myGoService.exe main.go

 

우선 명령프롬프트에서 console 실행

> myGoService.exe

 

윈도우 서비스 명령 사용을 위해 관리자 권한으로 명령 프롬프트 실행

 

서비스 등록 및 실행

sc create MyGoService binPath= "C:\workspace\myGoService\myGoService.exe liveMode"

sc start MyGoService

 

서비스 중지 및 삭제

sc stop MyGoService
sc delete MyGoService