You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Server 2019下Go程序无法作为Windows服务启动报错

Go编写的REST API部署为Windows服务启动失败排查方案

核心故障原因与修复

1. 服务注册参数错误

你当前使用的New-Service命令中BinaryPathName参数的引号嵌套错误,系统会将包含--service参数的完整字符串识别为可执行文件路径,无法找到对应文件导致启动失败。
先执行以下命令删除错误注册的服务:

sc.exe delete AHS

再使用修正后的参数重新注册服务,注意可执行文件路径单独用双引号包裹,参数放在引号外部:

$params = @{
  Name = "AHS"
  BinaryPathName = '"C:\Temp\ah.exe" --service'
  DisplayName = "AH Service"
  StartupType = "Manual"
  Description = "This is a test service."
}
New-Service @params

2. 代码工作目录异常

Windows服务默认工作目录为C:\Windows\System32,并非可执行文件所在目录。你代码中使用相对路径写入log.txt,会出现两种异常:一是日志文件写入到System32目录不符合预期,二是默认服务账号无System32写入权限时会直接导致进程崩溃退出。
在main函数最开头添加以下代码,将工作目录切换为可执行文件所在目录:

// 先在import块引入"path/filepath"
exePath, err := os.Executable()
if err == nil {
    _ = os.Chdir(filepath.Dir(exePath))
}

同时补全service库的配置项,避免平台兼容性问题:

serviceConfig := &service.Config{
    Name:        serviceName,
    DisplayName: "AH Service",
    Description: "This is a test service.",
}

3. 日志写入逻辑bug

你当前的writeToFile方法每次调用os.Create都会截断覆盖原有文件,既无法保留历史日志,文件被占用时还会抛出错误。建议改为追加写入模式:

func writeToFile(str string, fileName string) error {
    file, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        return err
    }
    defer file.Close()
    _, err = file.WriteString(time.Now().Format(time.RFC3339) + " " + str)
    return err
}

通用排查步骤

  • 先直接在命令行执行C:\Temp\ah.exe --service,确认程序本身无逻辑错误,可正常运行、生成日志文件。如果命令行下无法运行,先修复程序本身的bug再注册服务。
  • 打开Windows事件查看器,依次进入「Windows日志」-「应用程序」,筛选来源为Service Control Manager或对应服务名的错误条目,可直接查看服务启动失败的具体原因(如文件不存在、权限不足、进程退出码等)。
  • 如果程序需要访问网络共享、特殊权限目录,可在服务属性的「登录」选项卡中,将服务运行账号修改为拥有对应权限的本地账号,默认的Local System账号无网络资源访问权限。

内容的提问来源于stack exchange,提问作者Mohsen Kamrani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:51:13