wmi

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2019 License: MIT Imports: 9 Imported by: 5

README

wmi

GoDoc Go Report Card

Package wmi provides a WQL interface to Windows WMI.

Note: It interfaces with WMI on the local machine, therefore it only runs on Windows.

Example

Print names of the currently running processes

package main

import (
   "fmt"
   "log"

   "github.com/bi-zone/wmi"
)

// When we use `wmi.CreateQuery` the name of the struct should match querying
// WMI class name.
type Win32_Process struct {
   PID       uint32 `wmi:"ProcessId"`
   Name      string
   UserField int `wmi:"-"`
}

func main() {
   var dst []Win32_Process

   q := wmi.CreateQuery(&dst, "")
   fmt.Println(q)

   if err := wmi.Query(q, &dst); err != nil {
   	log.Fatal(err)
   }
   for _, v := range dst {
   	fmt.Println(v.PID, v.Name)
   }
}

A more sophisticated examples are located at in examples folder.

Benchmarks

Using DefaultClient, SWbemServices or SWbemServicesConnection differ in a number of setup calls doing to perform each query (from the most to the least).

Estimated overhead is shown below:

BenchmarkQuery_DefaultClient   5000  33529798 ns/op
BenchmarkQuery_SWbemServices   5000  32031199 ns/op
BenchmarkQuery_SWbemConnection 5000  30099403 ns/op

You could reproduce the results on your machine running:

go test -run=NONE -bench=Query -benchtime=120s

Documentation

Overview

Package wmi provides a WQL interface for WMI on Windows.

Example code to print names of running processes:

    // When we use `wmi.CreateQuery` the name of the struct should match querying
    // WMI class name.
    type Win32_Process struct {
    	PID       uint32 `wmi:"ProcessId"`
    	Name      string
    	UserField int `wmi:"-"`
    }

    func main() {
    	var dst []Win32_Process

	    q := wmi.CreateQuery(&dst, "")
	    fmt.Println(q)

	    if err := wmi.Query(q, &dst); err != nil {
    		log.Fatal(err)
    	}
    	for _, v := range dst {
    		fmt.Println(v.PID, v.Name)
    	}
    }

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAlreadyRunning is returned when NotificationQuery is already running.
	ErrAlreadyRunning = errors.New("already running")
)

Functions

This section is empty.

Types

type NotificationQuery

type NotificationQuery struct {
	Decoder

	sync.Mutex
	// contains filtered or unexported fields
}

NotificationQuery represents subscription to the WMI events. For more info see https://docs.microsoft.com/en-us/windows/desktop/wmisdk/swbemservices-execnotificationquery

func NewNotificationQuery

func NewNotificationQuery(eventCh interface{}, query string) (*NotificationQuery, error)

NewNotificationQuery creates a NotificationQuery from the given WQL @query string. The method just creates the object and does no WMI calls, so all WMI errors (query syntax, connection, etc.) will be returned on query start.

@eventCh should be a channel of structures or structure pointers. The structure type should satisfy limitations described in `Decoder.Unmarshal`.

Returns error if @eventCh is not `chan T` nor `chan *T`.

func (*NotificationQuery) SetConnectServerArgs

func (q *NotificationQuery) SetConnectServerArgs(args ...interface{})

SetConnectServerArgs sets `SWbemLocator.ConnectServer` args. Args are directly passed to `ole` call and support most of primitive types. Should be called before query being started.

Args reference: https://docs.microsoft.com/en-us/windows/desktop/wmisdk/swbemlocator-connectserver Passing details: https://github.com/go-ole/go-ole/blob/master/idispatch_windows.go#L60

func (*NotificationQuery) SetNotificationTimeout

func (q *NotificationQuery) SetNotificationTimeout(t time.Duration)

SetNotificationTimeout specifies a time query could send waiting for the next event at the worst case. Waiting for the next event locks notification thread so in other words @t specifies a time for notification thread to react to the `Stop()` command at the worst.

Default NotificationTimeout is 1s. It could be safely changed after the query `Start()`.

Setting it to negative Duration makes that interval infinite.

func (*NotificationQuery) StartNotifications

func (q *NotificationQuery) StartNotifications() (err error)

StartNotifications connects to the WMI service and starts receiving notifications generated by the query.

Errors are usually happen on initialization phase (connect to WMI, query execution, first result unmarshalling) so you could assume that "it's either starts and going to give me notifications or fails fast enough".

func (*NotificationQuery) Stop

func (q *NotificationQuery) Stop()

Stop stops the running query waiting until everything is released. It could take some time for query to receive a stop signal. See `SetNotificationTimeout` for more info.

Directories

Path Synopsis
examples
events command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL