Skip to content

Commit f3aa922

Browse files
authored
Merge pull request #386 from laozc/wmi-library-system-api
feat: Use WMI to implement System API to reduce PowerShell overhead (library version)
2 parents 986607e + e0651ef commit f3aa922

File tree

1,395 files changed

+423959
-53
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,395 files changed

+423959
-53
lines changed

pkg/cim/system.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package cim
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/microsoft/wmi/pkg/base/query"
10+
"github.com/microsoft/wmi/server2019/root/cimv2"
11+
)
12+
13+
var (
14+
BIOSSelectorList = []string{"SerialNumber"}
15+
ServiceSelectorList = []string{"DisplayName", "State", "StartMode"}
16+
)
17+
18+
type ServiceInterface interface {
19+
GetPropertyName() (string, error)
20+
GetPropertyDisplayName() (string, error)
21+
GetPropertyState() (string, error)
22+
GetPropertyStartMode() (string, error)
23+
GetDependents() ([]ServiceInterface, error)
24+
StartService() (result uint32, err error)
25+
StopService() (result uint32, err error)
26+
Refresh() error
27+
}
28+
29+
// QueryBIOSElement retrieves the BIOS element.
30+
//
31+
// The equivalent WMI query is:
32+
//
33+
// SELECT [selectors] FROM CIM_BIOSElement
34+
//
35+
// Refer to https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/cim-bioselement
36+
// for the WMI class definition.
37+
func QueryBIOSElement(selectorList []string) (*cimv2.CIM_BIOSElement, error) {
38+
biosQuery := query.NewWmiQueryWithSelectList("CIM_BIOSElement", selectorList)
39+
instances, err := QueryInstances("", biosQuery)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
bios, err := cimv2.NewCIM_BIOSElementEx1(instances[0])
45+
if err != nil {
46+
return nil, fmt.Errorf("failed to get BIOS element: %w", err)
47+
}
48+
49+
return bios, err
50+
}
51+
52+
// GetBIOSSerialNumber returns the BIOS serial number.
53+
func GetBIOSSerialNumber(bios *cimv2.CIM_BIOSElement) (string, error) {
54+
return bios.GetPropertySerialNumber()
55+
}
56+
57+
// QueryServiceByName retrieves a specific service by its name.
58+
//
59+
// The equivalent WMI query is:
60+
//
61+
// SELECT [selectors] FROM Win32_Service
62+
//
63+
// Refer to https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-service
64+
// for the WMI class definition.
65+
func QueryServiceByName(name string, selectorList []string) (*cimv2.Win32_Service, error) {
66+
serviceQuery := query.NewWmiQueryWithSelectList("Win32_Service", selectorList, "Name", name)
67+
instances, err := QueryInstances("", serviceQuery)
68+
if err != nil {
69+
return nil, err
70+
}
71+
72+
service, err := cimv2.NewWin32_ServiceEx1(instances[0])
73+
if err != nil {
74+
return nil, fmt.Errorf("failed to get service %s: %w", name, err)
75+
}
76+
77+
return service, err
78+
}
79+
80+
// GetServiceName returns the name of a service.
81+
func GetServiceName(service ServiceInterface) (string, error) {
82+
return service.GetPropertyName()
83+
}
84+
85+
// GetServiceDisplayName returns the display name of a service.
86+
func GetServiceDisplayName(service ServiceInterface) (string, error) {
87+
return service.GetPropertyDisplayName()
88+
}
89+
90+
// GetServiceState returns the state of a service.
91+
func GetServiceState(service ServiceInterface) (string, error) {
92+
return service.GetPropertyState()
93+
}
94+
95+
// GetServiceStartMode returns the start mode of a service.
96+
func GetServiceStartMode(service ServiceInterface) (string, error) {
97+
return service.GetPropertyStartMode()
98+
}
99+
100+
// Win32Service wraps the WMI class Win32_Service (mainly for testing)
101+
type Win32Service struct {
102+
*cimv2.Win32_Service
103+
}
104+
105+
func (s *Win32Service) GetDependents() ([]ServiceInterface, error) {
106+
collection, err := s.GetAssociated("Win32_DependentService", "Win32_Service", "Dependent", "Antecedent")
107+
if err != nil {
108+
return nil, err
109+
}
110+
111+
var result []ServiceInterface
112+
for _, coll := range collection {
113+
service, err := cimv2.NewWin32_ServiceEx1(coll)
114+
if err != nil {
115+
return nil, err
116+
}
117+
118+
result = append(result, &Win32Service{
119+
service,
120+
})
121+
}
122+
return result, nil
123+
}
124+
125+
type Win32ServiceFactory struct {
126+
}
127+
128+
func (impl Win32ServiceFactory) GetService(name string) (ServiceInterface, error) {
129+
service, err := QueryServiceByName(name, ServiceSelectorList)
130+
if err != nil {
131+
return nil, err
132+
}
133+
134+
return &Win32Service{Win32_Service: service}, nil
135+
}

0 commit comments

Comments
 (0)