当前位置: 首页 > news >正文

go程序在windows服务中优雅开启和关闭

  本篇主要是讲述一个go程序,如何在windows服务中优雅开启和关闭,废话不多说,开搞!!!
  使用方式:go程序 + net服务启动

Ⅰ 开篇不利

  Windows go进程编译后,为一个.exe文件,直接执行即可运行

 net start tamper_proof_refactored

  启动后,发现windows服务根本不认识这个go二进制文件,完全起不来
在这里插入图片描述

注意:因为普通的程序无法处理Windows服务特有的消息,普通的Go程序也无法在服务模式运行。

Ⅱ 需求拆解

  现在知道一个问题了:普通的go程序启动服务后,服务会出现"无响应控制功能"

现在是想要实现什么?
  go程序编译的二进制文件,可以被当作windows服务,稳定在后台执行,并可优雅开启和关闭

Ⅲ 具体实现

  找到一个go的官方库,用于实现windows服务注册和启动的

golang.org/x/sys/windows/svc

具体实现逻辑如下


func (m *myService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinuechanges <- svc.Status{State: svc.StartPending}go Star() // 启动go程序的主程序【需要有一个主入口函数】changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
loop:for {c := <-rswitch c.Cmd {case svc.Interrogate:changes <- c.CurrentStatuscase svc.Stop, svc.Shutdown:Exit() // 停止你的程序break loopcase svc.Pause:// 添加你的程序的暂停逻辑changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}case svc.Continue:// 添加你的程序的继续逻辑changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}default:log.Printf("unexpected control request #%d", c)}}changes <- svc.Status{State: svc.StopPending}return
}
func RunService() {err := svc.Run("tamper_proof_refactored", &myService{})if err != nil {log.Fatal(err)}fmt.Println("服务已启动")
}

启动后,直接终端查看下效果
在这里插入图片描述
写了一个服务状态判断,打印出的服务当前状态日志
在这里插入图片描述

写完后,就可以正常的服务启动和关闭了,下面是详细的服务启动/关闭指令

sc create MyService binPath= "C:\path\to\your\program\tamper_proof_XXXX.exe"  //创建服务
net start MyService   // 开启服务
net stop   myserver   // 暂停服务
sc  delete myserver   // 删除服务

参考文献:

  • Go语言和Windows服务

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 隐写工具steghide linux编译安装
  • uni-app 将base64图片转换成临时地址
  • 使用 Python 中的 ELSER 进行Serverless 语义搜索:探索夏季奥运会历史
  • jenkins使用docker api配置自签证书 +发布项目
  • c++----类与对象(下)
  • 数据结构与算法 - 数组
  • 大模型下的视频理解video understanding
  • K8S及Rancher部署
  • 记一些零碎的只是点和一些安全工具的使用(这里建议将漏洞原理搞清楚,然后可以尝试手动和使用工具)
  • 系统设计中15 个最重要的权衡
  • 艾体宝干货 | 如何分析关键网络性能指标?持续接收样品试用申请!
  • 行为验证码——产品
  • easyadmin layui js监听返回结果,进行token验证防止连点
  • 详细说明Java中Map和Set接口的使用方法
  • 全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用
  • 【译】JS基础算法脚本:字符串结尾
  • Angular Elements 及其运作原理
  • CSS 提示工具(Tooltip)
  • PHP 的 SAPI 是个什么东西
  • Python学习之路16-使用API
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Transformer-XL: Unleashing the Potential of Attention Models
  • Vue ES6 Jade Scss Webpack Gulp
  • 聊聊hikari连接池的leakDetectionThreshold
  • 使用权重正则化较少模型过拟合
  • 事件委托的小应用
  • 数组的操作
  • 算法-插入排序
  • 线上 python http server profile 实践
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 怎么将电脑中的声音录制成WAV格式
  • ​字​节​一​面​
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • $ git push -u origin master 推送到远程库出错
  • (1)svelte 教程:hello world
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (day18) leetcode 204.计数质数
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (力扣)1314.矩阵区域和
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (学习总结16)C++模版2
  • (一)Dubbo快速入门、介绍、使用
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • **PHP二维数组遍历时同时赋值
  • .bat批处理出现中文乱码的情况
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?