You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

139 lines
2.9 KiB

package main
import (
"fmt"
"github.com/shirou/gopsutil/winservices"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
"time"
)
// 定义Service对象
type Service struct {
Name string
srv *winservices.Service
Config mgr.Config
Status winservices.ServiceStatus
}
// 得到Service信息
func (s *Service) getServiceDetail() error {
defer func() {
if err := recover(); err != nil {
return
}
}()
err := s.srv.GetServiceDetail()
if err != nil {
// 服务打开失败
return err
}
s.Name = s.srv.Name
s.Status = s.srv.Status
s.Config = s.srv.Config
return nil
}
// 启动一个服务
func (s *Service) StartService() error {
return StartService(s.Name)
}
// 停止一个服务
func (s *Service) StopService() error {
return StopService(s.Name)
}
// 服务是否已经停止
func (s *Service) IsStop() bool {
return s.Status.State == svc.Stopped
}
// 服务是否正在运行
func (s *Service) IsRunning() bool {
return s.Status.State == svc.Running
}
// 新建一个Service对象
func NewWinService(serviceName string) (*Service, error) {
winService, err := winservices.NewService(serviceName)
if err != nil {
return nil, err
}
result := &Service{
Name: serviceName,
srv: winService,
}
err = result.getServiceDetail()
return result, err
}
// 得到Service信息
func GetServiceInfo(serviceName string) (*winservices.Service, error) {
defer func() {
if err := recover(); err != nil {
return
}
}()
newservice, _ := winservices.NewService(serviceName)
err := newservice.GetServiceDetail()
if err != nil {
fmt.Println(serviceName, "服务打开失败!")
return nil, err
}
return newservice, nil
}
// 启动一个服务
func StartService(name string) error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(name)
if err != nil {
return fmt.Errorf("无法访问服务: %v", err)
}
defer s.Close()
err = s.Start("is", "manual-started")
if err != nil {
return fmt.Errorf("无法启动服务:: %v", err)
}
return nil
}
// 停止一个服务
func StopService(name string) error {
return ControlService(name, svc.Stop, svc.Stopped)
}
// 改一个服务状态,
func ControlService(name string, c svc.Cmd, to svc.State) error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(name)
if err != nil {
return fmt.Errorf("无法访问服务: %v", err)
}
defer s.Close()
status, err := s.Control(c)
if err != nil {
return fmt.Errorf("无法发送控制=%d: %v", c, err)
}
timeout := time.Now().Add(10 * time.Second)
for status.State != to {
if timeout.Before(time.Now()) {
return fmt.Errorf("等待服务进入状态超时=%d", to)
}
time.Sleep(300 * time.Millisecond)
status, err = s.Query()
if err != nil {
return fmt.Errorf("无法检索服务状态: %v", err)
}
}
return nil
}