Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
IT Security NachrichtenObservability should start with business outcomes, not infrastructure(22.09.2026 um 11:00 Uhr)
Sicherheitslücken (CVE)CISA orders feds to patch Zyxel flaw exploited for data theft(22.09.2026 um 10:53 Uhr)
AI & KI NachrichtenDeutscher KI-Markt legt 2026 um fast 50 % zu(22.09.2026 um 10:59 Uhr)
AI & KI NachrichtenKI-Regulierung in Deutschland: Grüne sehen deutliche Defizite(22.09.2026 um 11:04 Uhr)
IT Security NachrichtenKMU von Cyber-Attacken besonders gebeutelt - Versicherungsmagazin.de(22.09.2026 um 01:04 Uhr)
IT Security NachrichtenObservability should start with business outcomes, not infrastructure(22.09.2026 um 11:00 Uhr)
Sicherheitslücken (CVE)CISA orders feds to patch Zyxel flaw exploited for data theft(22.09.2026 um 10:53 Uhr)
AI & KI NachrichtenDeutscher KI-Markt legt 2026 um fast 50 % zu(22.09.2026 um 10:59 Uhr)
AI & KI NachrichtenKI-Regulierung in Deutschland: Grüne sehen deutliche Defizite(22.09.2026 um 11:04 Uhr)
IT Security NachrichtenKMU von Cyber-Attacken besonders gebeutelt - Versicherungsmagazin.de(22.09.2026 um 01:04 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Writing a Windows Service in Go

Table Of Contents Introduction What exactly is a windows "service"? Why Golang? Writing a windows service in Go Installing and Starting the Service Conclusion Complete Code Introduction Hello Devs, It's been a while since…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




Table Of Contents




  • Introduction

  • What exactly is a windows "service"?

  • Why Golang?

  • Writing a windows service in Go

  • Installing and Starting the Service

  • Conclusion

  • Complete Code






Introduction



Hello Devs, It's been a while since I wrote something windows-ish. So, today I want to guide you guys on how to write a Windows Service Application in Go. Yes, you heard it right, it's go language. In this tutorial blog, we'll cover some basic stuffs about Windows Service Applications and at the later part, I'll guide you through a simple code walk through where we write code for a Windows service which logs some information to a file. Without further ado, Let's get started...!






What exactly is a windows "service"?



A Windows Service Application a.k.a. Windows Services are tiny applications that runs in background. Unlike normal windows applications, they don't have a GUI or any forms of user interface. These service applications starts to run when the computer boots up. It runs irrespective of which user account it's running in. It's lifecycle (start, stop, pause, continue etc.,) are controlled by a program called Service Control Manager (SCM).



So, from this we can understand that we should write our Windows Service in such a way that the SCM should interact with our Windows Service and manage it's lifecycle.






Why Golang?



There are several factors where you may consider Go for writing Windows Services.






Concurrency



Go's concurrency model allows for faster and resource efficient processing. Go's goroutines allows us to write applications which can do multi-tasking without any blocking or deadlocking.






Simplicity



Traditionally, Windows Services are written using either C++ or C (sometimes C#) which not only results in a complex code, but also poor DX (Developer Experience). Go's implementation of Windows Services is straightforward and every line of code makes sense.






Static Binaries



You may ask, "Why not use even more simple language like python?". The reason is due to the interpreted nature of Python. Go compiles to a statically linked single file binary which is essential for a Windows Service to function efficiently. Go binaries doesn't require any runtime / interpreter. Go code can also be cross compiled.






Low Level Access



Though being a Garbage Collected language, Go provides solid support to interact with low level elements. We can easily invoke win32 APIs and general syscalls in go.



Alright, enough information. Let's code...






Writing a windows service in Go



This code walk-through assumes that you have a basic knowledge on Go syntax. If not, A Tour of Go would be a nice place to learn it.




  • Firstly, let's name our project. I'll name mines as cosmic/my_service. Create a go.mod file,




PS C:\> go mod init cosmic/my_service







  • Now we need to install golang.org/x/sys package. This package provides go language support for Windows OS related applications.




PS C:\> go get golang.org/x/sys







Note: This package also contains OS level go language support for UNIX based OS'es like Mac OS and Linux.





  • Create a main.go file. The main.go file contains main function, which acts as a entry-point for our Go application/service.


  • For creating a service instance, we need to write something called Service Context, which implements Handler interface from golang.org/x/sys/windows/svc.




So, the interface definition looks something like this




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






Execute function will be called by the package code at the start of the service, and the service will exit once the Execute completes.



We read service change requests from receive-only channel r and act accordingly. We should also keep our service updated with sending signals to send-only channel s. We can pass optional arguments to args parameter.



On exiting, we can return with the exitCode being 0 on a successful execution. We can also use svcSpecificEC for that.




  • Now, create a type named myService which will act as our Service Context.




type myService struct{}







  • After creating the type myService, add the above mentioned Execute as a method to it so that it implements Handler interface.




func (m *myService) Execute(args []string, r <-chan svc.ChangeRequest, status chan<- svc.Status) (bool, uint32) {
// to be filled
}







  • Now that we have successfully implemented the Handler interface, we can now start writing the actual logic.



Create a constant, with the signals that our service can accept from SCM.




const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue






Our main goal is the log some data every 30 seconds. So we need to define a thread safe timer for that.




tick := time.Tick(30 * time.Second)






So, we have done all the initialization stuffs. It's time to send START signal to the SCM. we're going to do exactly that,




status <- svc.Status{State: svc.StartPending}
status <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}






Now we're going to write a loop which acts as a mainloop for our application. Handling events in loop makes our application never ending and we can break the loop only when the SCM sends STOP or SHUTDOWN signal.




loop:
for {
select {
case <-tick:
log.Print("Tick Handled...!")
case c := <-r:
switch c.Cmd {
case svc.Interrogate:
status <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
log.Print("Shutting service...!")
break loop
case svc.Pause:
status <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
case svc.Continue:
status <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
default:
log.Printf("Unexpected service control request #%d", c)
}
}
}






Here we used a select statement to receive signals from channels. In first case, we handle the Timer's tick signal. This case receives signal every 30 seconds, as we declared before. We log a string "Tick Handled...!" in this case.



Secondly, we handle the signals from SCM via the receive-only r channel. So, we assign the value of the signal from r to a variable c and using a switch statement, we can handle all the lifecycle event/signals of our service. We can see about each lifecycle below,





  1. svc.Interrogate - Signal requested by SCM on a timely fashion to check the current status of the service.


  2. svc.Stop and svc.Shutdown - Signal sent by SCM when our service needs to be stopped or Shut Down.


  3. svc.Pause - Signal sent by SCM to pause the service execution without shutting it down.


  4. svc.Continue - Signal sent by SCM to resume the paused execution state of the service.



So, when on receiving either svc.Stop or svc.Shutdown signal, we break the loop. It is to be noted that we need to send STOP signal to the SCM to let the SCM know that our service is stopping.




status <- svc.Status{State: svc.StopPending}
return false, 1







  • Now we write a function called runService where we enable our service to run either in Debug mode or in Service Control Mode.




Note: It's super hard to debug Windows Service Applications when running on Service Control Mode. That's why we are writing an additional Debug mode.





func runService(name string, isDebug bool) {
if isDebug {
err := debug.Run(name, &myService{})
if err != nil {
log.Fatalln("Error running service in debug mode.")
}
} else {
err := svc.Run(name, &myService{})
if err != nil {
log.Fatalln("Error running service in debug mode.")
}
}
}







  • Finally we can call the runService function in our main function.




func main() {

f, err := os.OpenFile("debug.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalln(fmt.Errorf("error opening file: %v", err))
}
defer f.Close()

log.SetOutput(f)
runService("myservice", false) //change to true to run in debug mode
}







Note: We are logging the logs to a log file. In advanced scenarios, we log our logs to Windows Event Logger. (phew, that sounds like a tongue twister 😂)





  • Now run go build to create a binary '.exe'. Optionally, we can optimize and reduce the binary file size by using the following command,




PS C:\> go build -ldflags "-s -w"









Installing and Starting the Service



For installing, deleting, starting and stopping our service, we use an inbuilt tool called sc.exe



To install our service, run the following command in powershell as Administrator,




PS C:\> sc.exe create MyService <path to your service_app.exe>






To start our service, run the following command,




PS C:\> sc.exe start MyService






To delete our service, run the following command,




PS C:\> sc.exe delete MyService






You can explore more commands, just type sc.exe without any arguments to see the available commands.






Conclusion



As we can see, implementing Windows Services in go is straightforward and requires minimal implementation. You can write your own windows services which acts as a web server and more. Thanks for reading and don't forget to drop a ❤️.






Complete Code



Here is the complete code for your reference.




// file: main.go

package main

import (
"fmt"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/debug"
"log"
"os"
"time"
)

type myService struct{}

func (m *myService) Execute(args []string, r <-chan svc.ChangeRequest, status chan<- svc.Status) (bool, uint32) {

const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
tick := time.Tick(5 * time.Second)

status <- svc.Status{State: svc.StartPending}

status <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}

loop:
for {
select {
case <-tick:
log.Print("Tick Handled...!")
case c := <-r:
switch c.Cmd {
case svc.Interrogate:
status <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
log.Print("Shutting service...!")
break loop
case svc.Pause:
status <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
case svc.Continue:
status <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
default:
log.Printf("Unexpected service control request #%d", c)
}
}
}

status <- svc.Status{State: svc.StopPending}
return false, 1
}

func runService(name string, isDebug bool) {
if isDebug {
err := debug.Run(name, &myService{})
if err != nil {
log.Fatalln("Error running service in debug mode.")
}
} else {
err := svc.Run(name, &myService{})
if err != nil {
log.Fatalln("Error running service in debug mode.")
}
}
}

func main() {

f, err := os.OpenFile("E:/awesomeProject/debug.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalln(fmt.Errorf("error opening file: %v", err))
}
defer f.Close()

log.SetOutput(f)
runService("myservice", false)
}


Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Writing a Windows Service in Go

Thematisch verwandte Begriffe: Writing, Windows, Service · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94426 | A vulnerability was determined in xuxueli xxl-job up to 3.5.0. The impac…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick