golang windows服务失败,没有任何错误

标签 go windows-services

我使用 golang 编写了一个简单的 Windows 服务。

package main

import "golang.org/x/sys/windows/svc"
import "io/ioutil"
import "log"
import "encoding/json"
import "time"
import "strconv"
import "os"
import "./cmd"
import "golang.org/x/sys/windows/svc/eventlog"
import "fmt"

type myservice struct{}

func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
    log.Println("Starting service")
    const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
    changes <- svc.Status{State: svc.StartPending}
    changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
    StartService(r, changes)
    return
}

//RunService Runs the current application as a service.It will send the necessary flags to windows.
func RunService(maintServiceName string) {
    //var elog eventlog

    elog, evtErr := eventlog.Open(maintServiceName)
    if evtErr != nil {
        return
    }

    defer elog.Close()
    log.Println("Running service")
    elog.Info(1, fmt.Sprintf("starting %s service", maintServiceName))

    run := svc.Run
    sererr := run(maintServiceName, &myservice{})
    if sererr != nil {
        elog.Error(1, fmt.Sprintf("%s service failed: %v", maintServiceName, sererr))
    }
}

//StartService Starts the Service
func StartService(r <-chan svc.ChangeRequest, changes chan<- svc.Status) {
    const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
    jsonFile, err := os.Open("config.json")
    if err != nil {
        log.Fatalln("No configuration found")
    }
    byteVal, _ := ioutil.ReadAll(jsonFile)
    var result map[string]interface{}
    json.Unmarshal([]byte(byteVal), &result)
    var serverURL = result["serverURL"]
    var serviceName = result["serviceName"]
    var intervalStr = result["interval"].(string)
    var intervalInt, parseErr = strconv.ParseInt(intervalStr, 10, 32)
    if parseErr != nil {
        intervalInt = 60
    }

    log.Println("server Url ", serverURL)
    log.Println("service name ", serviceName)

    cmd.SetServerURL(serverURL.(string))
    cmd.SetServiceName(serviceName.(string))
    log.Println("Running Thread")

    go func() {
        for {
            log.Println("sleeping ")
            time.Sleep(time.Duration(intervalInt) * time.Second)
            cmd.Connect()
        }
    }()

    select {
    case c := <-r:
        if c.Cmd == svc.Stop || c.Cmd == svc.Shutdown {
            break
        }
        if c.Cmd == svc.Interrogate {
            changes <- c.CurrentStatus
            time.Sleep(100 * time.Millisecond)
            changes <- c.CurrentStatus
        }
        if c.Cmd == svc.Pause {
            changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
        }
        if c.Cmd == svc.Continue {
            changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
        }
    }

}
该应用程序大部分时间运行一两天都没有问题,但之后停止而没有任何错误。发生这种情况时,日志中的 sleep line 后没有日志。我可以添加任何内容以获取有关服务失败的更多信息。这里可能是什么问题?

最佳答案

我将首先在 select 周围添加一个循环。在 StartService (见 this example)。从您提供的代码看来,您的服务将在收到任何可能是问题的信号(包括暂停/询问)后退出。添加更多登录 StartService也可能是有益的(任何提供有关正在发生的事情的更多信息的东西都有帮助!)
如果这不能解决问题,那么值得添加 defer/recover在 go 例程和 StartService 中检查是否是 panic 导致了问题(只需将一些内容写入日志可能就足够了)。

关于golang windows服务失败,没有任何错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63735638/

相关文章:

windows-services - 从非管理员用户帐户启动/停止 Windows 服务

http - 如何重试 HTTP POST 请求

go - 当我从 tcp 缓冲区读取时,我应该为 mtu 值选择哪个数字

json - Golang,将 json 解码为自定义结构

go - 意外的同步池分配

java - Windows 服务登录前访问网络

visual-studio - 安装前停止服务

c# - 是否可以从 .net core 3.1 Windows 服务打印文档?

go - 树递归 - 如何避免 'missing return at end of function' ?

.net - 如何使用断点调试Windows服务?