Building Windows Services with Go: A Starting Point

A Generic Go Windows Service Template

I’m pleased to share go-windows-service.

What is go-windows-service?

The go-windows-service project is a template implementation that demonstrates how to create a proper Windows service using Go’s golang.org/x/sys/windows/svc package. Rather than being a feature-complete application, it’s designed as a reference implementation that you can clone, customize, and extend for your specific needs.

Why Use This Template?

Creating Windows services in Go can be tricky if you’re not familiar with the Windows service architecture. And let’s be honest, the Windows service API documentation sometimes feels like it was written during the Windows NT era and nobody bothered to update it since. This template handles all the boilerplate code for you - service control handlers, proper signal handling, event log integration, and all that fun stuff.

Instead of spending three days figuring out why your service won’t start (spoiler: it’s always the event log permissions), you can focus on implementing your actual business logic.

Getting Started

The project is straightforward to use:

  1. Clone the repository

    git clone https://gitlab.com/hocmodo/go-windows-service.git
    cd go-windows-service
    
  2. Build the service

    go build
    
  3. Install as a Windows service

    go-windows-service.exe -install
    
  4. Start the service

    sc start YourServiceName
    

Use Cases

This template is perfect for:

  • Background processing tasks - Long-running jobs that need to survive user logouts
  • System monitoring agents - Services that monitor system resources or application health
  • API servers - HTTP/gRPC servers that need to run as Windows services
  • Data collection agents - Services that gather and forward metrics or logs
  • Scheduled tasks - Jobs that need more control than Windows Task Scheduler provides

Customization

The template is designed to be easily customized. The main service logic is cleanly separated from the Windows service wrapper code, making it simple to:

  • Add your own business logic in the service execution loop
  • Implement configuration file reading
  • Integrate with databases or message queues
  • Add health check endpoints
  • Implement graceful shutdown procedures

A Practical Example

Here’s a simple example of how you might extend the template to create a file monitoring service:

func (m *myService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
    // Your custom initialization
    watcher := setupFileWatcher()
    defer watcher.Close()

    changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
    
    for {
        select {
        case c := <-r:
            switch c.Cmd {
            case svc.Stop, svc.Shutdown:
                // Cleanup and exit
                return
            }
        case event := <-watcher.Events:
            // Handle file system events
            handleFileEvent(event)
        }
    }
}

Project Status

This is a template project, meaning it’s intentionally kept minimal and generic. The goal is to provide a clean starting point rather than a feature-rich framework. This approach ensures the codebase remains easy to understand and modify for your specific requirements.

Contributing and Feedback

While this is primarily a template project, contributions that improve the base structure, fix bugs, or enhance documentation are always welcome. The project is hosted on GitLab where you can report issues or submit merge requests.

Now go build something useful! Or at least something that runs in the background without crashing. We’re not picky.