1

I am using this go WMI package to monitor windows processes which are starting and stopping. I have see the example an implemented my own methods using Win32_Process and __InstanceCreationEvent and __InstanceDeletionEvent.

Here is the sample for __InstanceDeletionEvent:

func (e *Events) deleteProcessNotify() error {

    query := `
              SELECT * FROM  __InstanceDeletionEvent
              WITHIN 1
              WHERE TargetInstance ISA 'Win32_Process'
    `

    events := make(chan event)

    q, err := wmi.NewNotificationQuery(events, query)
    if err != nil {
        return errors.New(
            fmt.Sprintf("Failed to create NotificationQuery; %s", err),
        )
    }

    go func() {
        e.errCh <- q.StartNotifications()
    }()

    log.Println("Listening for events", CLS)
    for {
        select {
        case ev := <-events:
            fmt.Printf("[%v] Name: %v, Pid: %v, PPid: %v\n",
                CLS,
                ev.Instance.Caption, ev.Instance.ProcessId, ev.Instance.ParentProcessId,
            )
        case sig := <-e.sigs:
            log.Printf("Got system signal %s; stopping", sig)
            q.Stop()
            return nil
        case err := <-e.errCh: // Query will never stop here w/o error.
            log.Printf("[ERR] Got StartNotifications error; %s", err)
            return nil
        }
    }

}

Above code works find but Win32_Process does not support ExitStatus and I decided to use Win32_ProcessTrace. But when I am closing applications, nothing is happening under case ev := <-events: this case.

Here is the method for Win32_ProcessTrace:

func (e *Events) deleteProcessNotify__Trace() error {

    query := `
              SELECT * FROM  __InstanceDeletionEvent
              WITHIN 1
              WHERE TargetInstance ISA 'Win32_ProcessTrace'
    `

    events := make(chan event)

    q, err := wmi.NewNotificationQuery(events, query)
    if err != nil {
        return errors.New(
            fmt.Sprintf("Failed to create NotificationQuery; %s", err),
        )
    }

    go func() {
        e.errCh <- q.StartNotifications()
    }()

    log.Println("Listening for events", CLS)
    for {
        select {
        case ev := <-events:

            // THIS EVENT IS NEVER OCCURRED AND 
            // I REALLY DONT KNOW WHY!!!
            //

            fmt.Println(ev)

            //
            //
            //


        case sig := <-e.sigs:
            log.Printf("Got system signal %s; stopping", sig)
            q.Stop()
            return nil
        case err := <-e.errCh: // Query will never stop here w/o error.
            log.Printf("[ERR] Got StartNotifications error; %s", err)
            return nil
        }
    }

}
M. Javad Mohebbi
  • 415
  • 1
  • 3
  • 14
  • Looks like you're doing it wrong; try to adapt the example from [there](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/krnlprov/win32-processstoptrace) instead. – kostix Feb 15 '22 at 14:08
  • I've already read the mentioned document, but had no luck to fix the issue. Do you note any wrong steps in my code. because from my point of view, I see things are correct. – M. Javad Mohebbi Feb 15 '22 at 14:42
  • 1
    I can only guess, but: 1) `Win32_ProcessTrace` is explicitly listed as a base class for other tracing classes; I hence have no idea whether you can at all use it directly; 2) Nowhere can I find a clear statement that the `__InstanceDeletionEvent` event gets triggered on that class—note that this event means "something" leaves the "scope"/"namespace" represented by a class; I would argue that a process termination is a regular tracing event—do you feel the difference? – kostix Feb 15 '22 at 14:45
  • 1
    … I mean, `Win32_Process` is a class which lists all currently available processes; when a process terminates, it's sensible an event is generated for it "leaving" that list. As opposed to this, a trace is just a stream of events—any process-related events of process starts or stops—if you'll take more specific instances of tracing classes. – kostix Feb 15 '22 at 14:46
  • @kostix, Thank you for the provided information. I was implemented the second method totally wrong. As I read your additional comments. I found that I should write my query as `query := "SELECT * FROM Win32_ProcessStopTrace"` instead of `SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_ProcessTrace'`. – M. Javad Mohebbi Feb 15 '22 at 15:32
  • So, have you managed to get proper events using the `Win32_ProcessTrace`? – kostix Feb 15 '22 at 15:56
  • No, I have managed it to get the proper event from `Win32_ProcessStopTrace`. – M. Javad Mohebbi Feb 16 '22 at 06:18

0 Answers0