Golang org x sys windows svc

Rendered for windows/amd64

Package svc provides everything required to build Windows service.

  • Constants
  • func IsAnInteractiveSession() (bool, error)deprecated
  • func IsWindowsService() (bool, error)
  • func Run(name string, handler Handler) error
  • func StatusHandle() windows.Handle
  • type Accepted
  • type ActivityStatus
  • type ChangeRequest
  • type Cmd
  • type Handler
  • type StartReason
    • func DynamicStartReason() (StartReason, error)
  • type State
  • type Status

This section is empty.

IsWindowsService reports whether the process is currently executing
as a Windows service.

Run executes service name by calling appropriate handler function.

func StatusHandle ¶


StatusHandle returns service status handle. It is safe to call this function
from inside the Handler.Execute because then it is guaranteed to be set.

Accepted is used to describe commands accepted by the service.
Note that Interrogate is always accepted.

ActivityStatus allows for services to be selected based on active and inactive categories of service state.

ChangeRequest is sent to the service Handler to request service status change.

Cmd represents service state change request. It is sent to a service
by the service manager, and should be actioned upon by the service.

type Handler ¶


type Handler interface {
	
	
	
	
	
	
	
	
	
	
	
	Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
}

Handler is the interface that must be implemented to build Windows service.

StartReason is the reason that the service was started.

func DynamicStartReason() (StartReason, error)

DynamicStartReason returns the reason why the service was started. It is safe
to call this function from inside the Handler.Execute because then it is
guaranteed to be set.

State describes service execution state (Stopped, Running and so on).

Status combines State and Accepted commands to fully describe running service.

import "golang.org/x/sys/windows/svc"

Package svc provides everything required to build Windows service.

  • Constants
  • func IsAnInteractiveSession() (bool, error)
  • func Run(name string, handler Handler) error
  • type Accepted
  • type ChangeRequest
  • type Cmd
  • type Handler
  • type State
  • type Status
  • Bugs

Package Files

event.go go13.go security.go service.go

Constants ¶

func IsAnInteractiveSession ¶

IsAnInteractiveSession determines if calling process is running interactively.
It queries the process token for membership in the Interactive group.
http://stackoverflow.com/questions/2668851/how-do-i-detect-that-my-application-is-running-as-service-or-in-an-interactive-s

func Run ¶

Run executes service name by calling appropriate handler function.

type Accepted ¶

Accepted is used to describe commands accepted by the service.
Note that Interrogate is always accepted.

type ChangeRequest ¶

type ChangeRequest struct {
    Cmd           Cmd
    CurrentStatus Status
}

ChangeRequest is sent to the service Handler to request service status change.

type Cmd ¶

Cmd represents service state change request. It is sent to a service
by the service manager, and should be actioned upon by the service.

type Handler ¶

type Handler interface {

    // Execute will be called by the package code at the start of
    // the service, and the service will exit once Execute completes.
    // Inside Execute you must read service change requests from r and
    // act accordingly. You must keep service control manager up to date
    // about state of your service by writing into s as required.
    // args contains service name followed by argument strings passed
    // to the service.
    // You can provide service exit code in exitCode return parameter,
    // with 0 being "no error". You can also indicate if exit code,
    // if any, is service specific or not by using svcSpecificEC
    // parameter.
    Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
}

Handler is the interface that must be implemented to build Windows service.

type State ¶

State describes service execution state (Stopped, Running and so on).

type Status ¶

type Status struct {
    State      State
    Accepts    Accepted
    CheckPoint uint32 // used to report progress during a lengthy operation
    WaitHint   uint32 // estimated time required for a pending operation, in milliseconds
}

Status combines State and Accepted commands to fully describe running service.

Bugs ¶

☞ There is no mechanism to run multiple services
inside one single executable. Perhaps, it can be overcome by
using RegisterServiceCtrlHandlerEx Windows api.

Directories ¶

Path Synopsis
debug Package debug provides facilities to execute svc.Handler on console.
eventlog Package eventlog implements access to Windows event log.
example Example service program that beeps.
mgr Package mgr can be used to manage Windows service programs.

Создание службы Windows на Golang

Создание службы Windows на Golang может показаться сложной задачей для многих разработчиков, но на самом деле это не так. В этой статье мы разберем, как создать службу Windows на языке программирования Golang.

Прежде чем мы начнем, давайте определим, что такое служба Windows. Служба Windows (Windows Service) — это приложение, которое работает в фоновом режиме и выполняет задачи в соответствии с определенным расписанием. Службы Windows могут использоваться для автоматизации различных задач, таких как резервное копирование данных, мониторинг системы и обслуживание.

Теперь, когда мы знаем, что такое служба Windows, мы можем рассмотреть, как создать ее на языке Golang.

Шаг 1: Установка Golang и настройка среды разработки

Первым шагом является установка языка программирования Golang и настройка среды разработки. Для установки Golang необходимо скачать соответствующий дистрибутив для вашей операционной системы с официального сайта Golang — https://golang.org/dl/. После установки необходимо настроить PATH переменную окружения, чтобы Golang был доступен из командной строки.

Для разработки на Golang рекомендуется использовать специализированные инструменты, такие как Visual Studio Code, GoLand, IntelliJ IDEA и другие.

Шаг 2: Создание проекта

Далее необходимо создать проект для нашей службы Windows. Создадим новую пустую папку и откроем ее в нашей среде разработки. В эту папку мы поместим два файла — main.go и service.go.

Шаг 3: Написание кода

Первый файл, main.go, будет содержать функцию main, которая будет запускать нашу службу. Для этого мы используем функцию svc.Run(), которая запустит службу и будет ждать ее завершения.

package main

import (
    "log"
    "os"
    "github.com/kardianos/service"
)

type program struct{}

func (p *program) Start(s service.Service) error {
    go p.run()
    return nil
}

func (p *program) run() {
    // TODO: Код для выполнения задач
}

func (p *program) Stop(s service.Service) error {
    return nil
}

func main() {
    svcConfig := &service.Config{
        Name:        "ServiceName",
        DisplayName: "Service Display Name",
        Description: "Service Description",
    }

    prg := &program{}
    s, err := service.New(prg, svcConfig)
    if err != nil {
        log.Fatal(err)
    }

    if len(os.Args) > 1 {
        if os.Args[1] == "install" {
            err = s.Install()
            if err != nil {
                log.Fatal(err)
            }
            log.Println("Service installed successfully.")
            return
        }

        if os.Args[1] == "uninstall" {
            err = s.Uninstall()
            if err != nil {
                log.Fatal(err)
            }
            log.Println("Service uninstalled successfully.")
            return
        }
    }

    err = s.Run()
    if err != nil {
        log.Fatal(err)
    }
}

В этом файле мы определили структуру program, которая представляет собой экземпляр нашей службы. Структура program содержит три метода: Start, run, Stop.

Метод Start запускает нашу службу и возвращает nil, если все прошло успешно. Метод run содержит код, который будет выполнен во время выполнения службы.

Метод Stop вызывается при остановке службы и возвращает nil, если все прошло успешно.

Второй файл, service.go, будет содержать дополнительный код, который позволит нашей службе работать как службе Windows. В этом файле мы определим функцию ServiceMain, которая будет вызываться при запуске службы и обрабатывать все соответствующие события.

// +build windows

package main

import (
    "golang.org/x/sys/windows/svc"
    "golang.org/x/sys/windows/svc/eventlog"
    //"golang.org/x/sys/windows/svc/mgr"
    "strconv"
)

func init() {
    // Установим максимальный размер журнала на 1024КБ.
    eventlog.Application = "ServiceName"
    eventlog.MaxSize = 1024 * 1024
}

func runService(name string, isDebug bool) {
    var err error
    var elog *eventlog.Log

    if !isDebug {
        elog, err = eventlog.Open(name)
        if err != nil {
            return
        }
        defer elog.Close()
    }

    prg := &program{}

    if isDebug {
        prg.run()
        return
    }

    err = svc.Run(name, prg)
    if err != nil {
        elog.Error(1, err.Error())
        return
    }
}

func debugService(name string) {
    runService(name, true)
}

func startService(name string) bool {
    // TODO: здесь нужно реализовать вызов функций API для запуска службы Windows.
    return true
}

func stopService(name string) bool {
    // TODO: здесь нужно реализовать вызов функций API для остановки службы Windows.
    return true
}

func installService(name string, displayName string, description string) bool {
    // TODO: здесь нужно реализовать вызов функций API для установки службы Windows.
    return true
}

func uninstallService(name string) bool {
    // TODO: здесь нужно реализовать вызов функций API для удаления службы Windows.
    return true
}

func main() {
    args := []string{"ServiceName"}

    if len(args) > 1 {
        switch args[1] {
        case "debug":
            debugService(args[0])
            return
        case "start":
            if startService(args[0]) {
                return
            }
        case "stop":
            if stopService(args[0]) {
                return
            }
        case "install":
            if installService(args[0], "Service Display Name", "Service Description") {
                return
            }
        case "uninstall":
            if uninstallService(args[0]) {
                return
            }
        }
    }

    usage := "Usage: " + args[0] + " <debug|start|stop|install|uninstall>"
    exitCode := 1
    if len(args) > 1 {
        exitCode = 0
    }

    println(usage)
    println("")
    println("Options:")
    println("  debug      Run in debug mode.")
    println("  start      Start service.")
    println("  stop       Stop service.")
    println("  install    Install service.")
    println("  uninstall  Uninstall service.")

    panic(strconv.Itoa(exitCode))
}

В этом файле мы определили функции для установки, удаления, запуска и остановки службы Windows. Мы также определили функцию main, которая будет обрабатывать команды, переданные в нашу службу из командной строки.

Шаг 4: Компиляция и запуск

После того, как мы создали необходимые файлы кода, мы можем скомпилировать проект и запустить нашу службу. Для компиляции проекта используем команду go build.

go build -o ServiceName.exe

После успешной компиляции мы получим файл ServiceName.exe, который можно запустить на компьютере под управлением Windows.

Чтобы установить службу, необходимо запустить команду install.

ServiceName.exe install

После успешной установки службы Windows мы можем ее запустить командой start и остановить командой stop.

ServiceName.exe start
ServiceName.exe stop

Чтобы удалить службу, необходимо запустить команду uninstall.

ServiceName.exe uninstall

В заключение мы рассмотрели, как создать службу Windows на языке Golang. Создание службы Windows может быть полезно для выполнения различных задач в фоновом режиме, например, для автоматизации определенных процессов на компьютере под управлением Windows. Благодаря использованию языка программирования Golang мы можем создавать быстрые, надежные и эффективные службы Windows.

I am trying to create a windows service as specified here

service.go has the following;

import (
    "fmt"
    ...

    "golang.org/x/sys/windows/svc"
    "golang.org/x/sys/windows/svc/debug"
    "golang.org/x/sys/windows/svc/eventlog"
)

So in the directory where my application is I enter the command

go get golang.org/x/sys/windows/svc/eventlog

The response is

can't load package: package golang.org/x/sys/windows/eventlog: cannot find package "golang.org/x/sys/windows/eventlog" in any of:
    C:\Program Files\Go\src\golang.org\x\sys\windows\eventlog (from $GOROOT)

    C:\Users\Paul\go\src\golang.org\x\sys\windows\eventlog (from $GOPATH)

I thought «go get» was supposed to download the package. How do I get a copy onto my system so that I can run my program?

asked May 17, 2018 at 6:13

CarbonMan's user avatar

1

If you check https://github.com/golang/sys what you are trying to get is src file within the repo so you have to get the whole repo to be able to get the src you need.

It’s part of a larger package

answered May 17, 2018 at 6:21

Nathanael Mkaya's user avatar

Comments

@AlexSiLive

What version of Go are you using (go version)?

$ go version
go version go1.14.4 windows/amd64

Does this issue reproduce with the latest release?

Yes.
Go version: go1.14.4
x/sys version: v0.0.0-20200625212154-ddb9806d33ae

What operating system and processor architecture are you using (go env)?

go env Output

$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\alex\AppData\Local\go-build
set GOENV=C:\Users\alex\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=*
set GOOS=windows
set GOPATH=C:\Users\alex\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=E:\WorkGo\src\golang.org\x\sys\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\A6473~1.POG\AppData\Local\Temp\go-build406331230=/tmp/go-build -gno-record-gcc-switches
GOROOT/bin/go version: go version go1.14.4 windows/amd64
GOROOT/bin/go tool compile -V: compile version go1.14.4
gdb --version: GNU gdb (GDB) 7.9.1

What did you do?

Problem:
Building a windows service using x/sys/windows/svc on go1.14+ will cause a service to terminate unexpectedly on system shutdown (SERVICE_CONTROL_SHUTDOWN command).

How to reproduce:
Build a default example for x/sys/windows/svc on go1.13 and go1.14. The latter will be terminated unexpectedly and produce a corresponding event in the event log (7034), while the former one will stop just fine.

Remarks:

  • A service can be stopped and started via service manager without an issue, the problem occurs on system shutdown or reboot.
  • Reverting x/sys/windows/svc to initial commits does nothing, i.e. the problem, probably, somewhere in-between go1.13 and go1.14.
    go_svc_7034.zip

@networkimprov

@dmitshur
dmitshur

added
the

NeedsInvestigation

Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

label

Jul 11, 2020

@alexbrainman

@AlexSiLive

Thank you for reporting the issue and the steps to reproduce the problem. Yes, I can see shutdown event sent for service compiled with go1.13.12, but not with current tip.

We need to try to use git bisect command to find commit that broken the code (it is, probably, https://go-review.googlesource.com/c/go/+/187739/ ). Unfortunately I don’t have time to run bisect now, but I will do it when I have time. Unless someone beats me to it.

Alex

This was referenced

Jul 12, 2020

@AlexSiLive

@AlexSiLive

I was able to make a dirty fix for this without modifying runtime by adding signal.Notify handling to a wrapping package.
Something similar can be done to x/sys/windows/svc itself:
`

...
func Run(name string, handler Handler) error {
	runtime.LockOSThread()

	tid := windows.GetCurrentThreadId()

	s, err := newService(name, handler)
	if err != nil {
		return err
	}

	signals := make(chan os.Signal, 1)
	signal.Notify(signals)

	go func() {
		for sig := range signals {
			if sig == windows.SIGTERM {
				signal.Stop(signals)
				s.c <- ctlEvent{cmd: Shutdown} // todo: some checks here, i.e. for SERVICE_ACCEPT_SHUTDOWN

				return
			}
		}
	}()
...

`

Please note, that following didn’t work for me (unless I’m doing something wrong):
`

signals := make(chan os.Signal, 1)
signal.Notify(signals, windows.SIGTERM) // <- specifying SIGTERM doesn't seem to work.

go func() {
	<- signals // <- this never triggers if SIGTERM is specified (mock program with SIGINT works though).
	signal.Stop(signals)
	s.c <- ctlEvent{cmd: Shutdown} // todo: some checks here, i.e. for SERVICE_ACCEPT_SHUTDOWN
}()

`

@JohanKnutzen

@AlekSi

I believe that our issues are related. I’ve got another workaround for this that overrides handling in go of that particular event in Windows:
40167

@gopherbot

@alexbrainman

Indeed, commenting out this clause resolves the issue:

Cool. Thanks for checking that.

We just need to come up with a solution here.

Alex

@AlekSi

@gopherbot

@alexbrainman

@aclements

This issue is with golang.org/x/sys/windows/svc package.

The problem was introduced in

https://go-review.googlesource.com/c/go/+/187739/

After the CL 187739, every Windows service would not receive «shutdown» event. When computer is shutdown, Go service just exits, instead of handling «shutdown» event.

@zx2c4 sent a fix for this issue

https://golang.org/cl/242280

And the fix is in runtime package.

Both Jason and I think the fix should be back-ported to Go 1.14 (Go 1.13 is good). Should we submit CL 242280 now? Should we wait for tree to be opened first? Do you agree CL 242280 should be back-ported?

There is some risk involved. Here, in particular, we don’t even have a test for the fix — you need to reboot computer to test our fix.

What do you think?

Thank you.

Alex

@networkimprov

@gopherbot

@gopherbot

@gopherbot

@gopherbot

@zx2c4

gopherbot

pushed a commit
that referenced
this issue

Aug 22, 2020

@zx2c4

@dmitshur

The service handler needs to handle CTRL+C-like events -- including
those sent by the service manager itself -- using the default Windows
implementation if no signal handler from Go is already listening to
those events. Ordinarily, the signal handler would call exit(2), but we
actually need to allow this to be passed onward to the service handler.
So, we detect if we're in a service and skip calling exit(2) in that
case, just like we do for shared libraries.

Updates #40167.
Updates #40074.
Fixes #40412.

Change-Id: Ia77871737a80e1e94f85b02d26af1fd2f646af96
Reviewed-on: https://go-review.googlesource.com/c/go/+/244959
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>

gopherbot

pushed a commit
that referenced
this issue

Aug 22, 2020

@zx2c4

@dmitshur

The service handler needs to handle CTRL+C-like events -- including
those sent by the service manager itself -- using the default Windows
implementation if no signal handler from Go is already listening to
those events. Ordinarily, the signal handler would call exit(2), but we
actually need to allow this to be passed onward to the service handler.
So, we detect if we're in a service and skip calling exit(2) in that
case, just like we do for shared libraries.

Updates #40167.
Updates #40074.
Fixes #40411.

Change-Id: Ia77871737a80e1e94f85b02d26af1fd2f646af96
Reviewed-on: https://go-review.googlesource.com/c/go/+/244958
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>

@golang
golang

locked and limited conversation to collaborators

Aug 15, 2021

  • Going into windows firewall outbound rules unblocking adobe unlicensed pop up
  • Google classroom download for windows
  • Google keep download for windows
  • Google chrome для windows 7 32 bit torrent
  • Google chromecast скачать для windows 10