Friday, October 4, 2024
HomeGolangMy Go utility works tremendous in interactive mode, nevertheless it fails to...

My Go utility works tremendous in interactive mode, nevertheless it fails to begin accurately when run as a Home windows service – Getting Assist


Good day all people,

I’ve a Go utility that I wish to run as a Home windows service. After I execute the applying instantly (interactive mode), every part works as anticipated, together with logging to a file. Nevertheless, when I attempt to run it as a Home windows service, it fails to begin, and I get the next error:

StartService FAILED 1053: The service didn’t reply to the beginning or management request in a well timed vogue.

What I’ve Tried

  1. Logging to a File:
  • I tried to initialize logging to a file within the listing the place the executable is situated utilizing the os.OpenFile technique. This works tremendous in interactive mode however doesn’t create or write to the log file when run as a service.
  1. Altering File Path for Logging:
  • I attempted altering the log file path to a less complicated location (like d:Logs), nevertheless it nonetheless didn’t resolve the problem when operating as a service.
  1. Checking Permissions:
  • I ensured that the service runs with administrator privileges. I additionally verified that the listing the place the log file is meant to be written exists and has the suitable write permissions.
  1. Utilizing sc begin for Debugging:
  • I attempted utilizing sc begin som.kalenderview debug to begin the service in debug mode, however I encountered the identical 1053 error.

The error happens instantaneous after beginning the service.

  • The service is configured accurately with sc create and runs beneath an administrator account.
  • I’m utilizing the golang.org/x/sys/home windows/svc package deal to handle the Home windows service.
  • The service appears to begin efficiently (as indicated by the service management supervisor) however instantly fails with error 1053, suggesting it doesn’t reply inside the timeout interval.

package deal essential

import (
	"encoding/xml"
	"flag"
	"fmt"
	"html/template"
	"log"
	"internet/http"
	"os"
	"path/filepath"
	"type"
	"strconv"
	"strings"
	"time"

	"golang.org/x/sys/home windows/svc"
	"golang.org/x/sys/home windows/svc/eventlog"

	cfg "myapp/config"
	out "myapp/output"
	rq "myapp/requestdata"
)

var (
	staticDir    = getAbsDirPath() + "/static/"
	templatesDir = staticDir + "/templates"
	templates    = template.Should(template.ParseFiles(templatesDir + "/index.html"))
	model      string
)

var config cfg.Config

kind myService struct{}

func (m *myService) Execute(args []string, r <-chan svc.ChangeRequest, s chan<- svc.Standing) (bool, uint32) {
	const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
	s <- svc.Standing{State: svc.StartPending}

	elog, err := eventlog.Open("myapp")
	if err != nil {
		log.Fatalf("Didn't open occasion log: %v", err)
	}
	defer elog.Shut()

	// Sende sofort die Working-Meldung, um den SCM zu informieren
	s <- svc.Standing{State: svc.Working, Accepts: cmdsAccepted}
	elog.Information(1, "myapp-service began.")

	// Starte den HTTP-Server in einer separaten Goroutine, um Blockierungen zu vermeiden
	go func() {
		err := startHTTPServer(elog)
		if err != nil {
			elog.Error(1, fmt.Sprintf("Failed to begin HTTP server: %v", err))
		}
	}()

	// Warte auf Cease- oder Shutdown-Befehle
loop:
	for {
		choose {
		case c := <-r:
			swap c.Cmd {
			case svc.Cease, svc.Shutdown:
				elog.Information(1, "myapp-service is stopping.")
				break loop
			default:
				elog.Error(1, "Sudden management request.")
			}
		}
	}

	s <- svc.Standing{State: svc.StopPending}
	return false, 0
}

func startHTTPServer(elog *eventlog.Log) error {
	if elog != nil {
		elog.Information(1, "Beginning HTTP server...")
	} else {
		log.Println("Beginning HTTP server...")
	}

	http.HandleFunc("https://discussion board.golangbridge.org/", indexHandler)
	http.HandleFunc("/scripts/", staticHandler)
	http.HandleFunc("/css/", staticHandler)
	http.HandleFunc("/pictures/", staticHandler)

	err := http.ListenAndServe(":"+config.LocalPort, nil)
	if err != nil && elog != nil {
		elog.Error(1, fmt.Sprintf("Failed to begin HTTP server: %v", err))
	}
	return err
}

func init() {
	// Ermittelt den Pfad zur ausführbaren Datei
	exePath, err := os.Executable()
	if err != nil {
		log.Fatalf("Didn't get executable path: %v", err)
	}

	// Bestimmt das Verzeichnis der ausführbaren Datei
	exeDir := filepath.Dir(exePath)

	// Logdateipfad in demselben Verzeichnis wie die ausführbare Datei
	logFilePath := filepath.Be a part of(exeDir, "somkalenderview_debug.log")

	// Öffne die Logdatei und leite die Ausgaben dorthin um
	f, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("Didn't open log file: %v", err)
	}

	log.SetOutput(f) // Setze die Log-Ausgabe auf die Datei
	log.Println("Logging initialized efficiently in", logFilePath)
}


func essential() {
	isInteractive, err := svc.IsAnInteractiveSession()
	if err != nil {
		log.Fatalf("failed to find out if we're operating in an interactive session: %v", err)
	}

	if isInteractive {
		runInteractive()
	} else {
		runService()
	}

	var vFlag bool
	flag.BoolVar(&vFlag, "v", false, "present model")
	flag.Parse()

	if vFlag {
		println(model)
	}

	var weiter bool = true

	file, err := os.Open("config.xml")
	if err != nil {
		fmt.Println("Fehler beim Öffnen der XML-Datei:", err)
		weiter = false
	}
	defer file.Shut()

	// Konfigurationsdaten aus der XML-Datei lesen
	if weiter {
		if err := xml.NewDecoder(file).Decode(&config); err != nil {
			fmt.Println("Fehler beim Lesen der XML-Datei:", err)
			weiter = false
		}
	}
}

func runService() {
	run := svc.Run
	err := run("myapp", &myService{})
	if err != nil {
		log.Fatalf("did not run service: %v", err)
	}
}

func runInteractive() {
	log.Println("Working in interactive mode...")
	go startHTTPServer(nil) // Starte den HTTP-Server auch im interaktiven Modus
	for {
		time.Sleep(10 * time.Second)
	}
}

My service doesn’t run even after I take away the HTTP server code. The service fails to begin with error 1053 (“The service didn’t reply to the beginning or management request in a well timed vogue”). I’ve tried operating the service with none blocking operations (just like the HTTP server), nevertheless it nonetheless fails with the identical error.

The appliance runs completely tremendous in interactive mode (from the command line), together with logging to a file, nevertheless it fails to begin accurately when operating as a Home windows service.

What may very well be inflicting the service to fail even when the HTTP server code is eliminated?

Greatest regards Jens

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments