Skip to content

WindowsServiceApi.GetServices: ServiceController instances not disposed after enumeration #97

@Christophe-Rogiers

Description

@Christophe-Rogiers

Bug Description

ServiceController.GetServices() returns an array of ServiceController objects that each implement IDisposable and hold an underlying Windows service handle. In GetServices(), these objects are projected into DTOs but never disposed, leaking handles on every call.

Actual Behavior

// WindowsServiceApi.cs lines 146-154
public IEnumerable<WindowsServiceInfo> GetServices()
{
    return ServiceController.GetServices()
        .Select(s => new WindowsServiceInfo
        {
            ServiceName = s.ServiceName,
            DisplayName = s.DisplayName
        });
}

Each ServiceController in the array holds an unmanaged handle. Because the LINQ projection is deferred and no disposal occurs, handles leak until the GC finalizer runs.

Suggested Fix

Materialize the query and dispose each ServiceController explicitly:

public IEnumerable<WindowsServiceInfo> GetServices()
{
    var controllers = ServiceController.GetServices();
    try
    {
        return controllers.Select(s => new WindowsServiceInfo
        {
            ServiceName = s.ServiceName,
            DisplayName = s.DisplayName
        }).ToList();
    }
    finally
    {
        foreach (var sc in controllers)
            sc.Dispose();
    }
}

Environment

  • File: src/Servy.Core/Services/WindowsServiceApi.cs
  • Lines: 146-154

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions