Run Go Windows Service
Provides creating and running Go Windows Service
winsvc.DisablePanic is option to disable this behavior.context.Context for graceful self shutdownwinsvc.Run if it stops for a long time. winsvc.TimeoutStop is option which it default equals value 20sos.Chdir for easy using relative pathgo get -u github.com/itcomusic/winsvc
package mainimport ("context""log""net/http""os""time""github.com/itcomusic/winsvc")type Application struct {srv *http.Server}func main() {winsvc.Run(func(ctx context.Context) {app := New()if err := app.Run(ctx); err != nil {log.Printf("[ERROR] rest terminated with error, %s", err)return}log.Printf("[WARN] rest terminated")})// service has been just stopped, but process of the go has not stopped yet// that is why recommendation is to not write any logic}func New() *Application {mux := http.NewServeMux()server := &http.Server{Addr: "0.0.0.0:8080",Handler: mux,}mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {w.WriteHeader(200)w.Write([]byte("hello winsvc"))})mux.HandleFunc("/exit", func(w http.ResponseWriter, r *http.Request) {// service will be restartedos.Exit(1)})mux.HandleFunc("/shutdown", func(w http.ResponseWriter, r *http.Request) {// service will be restartedserver.Shutdown(context.TODO())})return &Application{srv: server}}func (a *Application) Run(ctx context.Context) error {log.Print("[INFO] started rest")go func() {defer log.Print("[WARN] shutdown rest server")// shutdown on context cancellation<-ctx.Done()c, _ := context.WithTimeout(context.Background(), time.Second*5)a.srv.Shutdown(c)}()log.Printf("[INFO] started http server on port :%d", 8080)return a.srv.ListenAndServe()}
$ sc.exe create "gowinsvc" binPath= "path\gowinsvc.exe" start= auto$ sc.exe failure "gowinsvc" reset= 0 actions= restart/5000