【问题标题】:I'm still getting null exception when using the System.Management can't figure out why使用 System.Management 时仍然出现空异常,无法弄清楚原因
【发布时间】:2014-08-26 14:03:25
【问题描述】:

每次我试图让它再次发生时都不会发生此异常,只有在我单击按钮以连续 4-5 次启动观察程序后,一个接一个...然后关闭我的程序,异常来了起来。

这是我正在使用管理的新课程。只有当我在新班级中启动观察者后关闭程序时才会发生这种情况:

我试图尝试并抓住,但它并没有停止任何一个。

using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace MinimizeCapture
{

    class WatchForWindow
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;

        private static ManagementEventWatcher watcher = null;

        public static void StartWatching()
        {
            try
            {
                WqlEventQuery query = new WqlEventQuery("Select * From __InstanceCreationEvent Within 2 Where TargetInstance Isa 'Win32_Process'");
                watcher = new ManagementEventWatcher(query);
                watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
                watcher.Start();
            }
            catch (Exception err)
            {
                string t = "err " + err.ToString();
            }
        }

        public static void StopWatching()
        {
            try
            {
                if (watcher != null)
                {
                    watcher.Stop();
                }
            }
            catch (Exception err)
            {
                string t = "err " + err.ToString();
            }
        }

        private static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
        {
            try
            {
                ManagementBaseObject obj = (ManagementBaseObject)e.NewEvent["TargetInstance"];
                string t = obj["Name"].ToString();
                GetHWND(t);
            }
            catch (Exception err)
            {
                string t = "err " + err.ToString();
            }
        }

        private static void GetHWND(string wName)
        {
            try
            {
                IntPtr hWnd = FindWindow("Chrome_WidgetWin_1 for Chrome", "Untitled - Notepad");
            }
            catch (Exception err)
            {
                string t = "err " + err.ToString();
            }
        }
    }
}

这是我使用 system.management 这个类的唯一地方 昨天我确定问题是当我关闭我的程序时,我还需要关闭观察者,所以我在类中添加了一个名为 StopWatching 的方法。

这是我在课堂上启动观察者的方式:

private void buttonSnap_Click(object sender, EventArgs e)
        {
            WatchForWindow.StartWatching();
        }

这就是我阻止它的方式:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            WatchForWindow.StopWatching();
        }

这是异常消息:

System.NullReferenceException was unhandled
  Message=Object reference not set to an instance of an object.
  Source=System.Management
  StackTrace:
       at System.Management.IWbemServices.CancelAsyncCall_(IWbemObjectSink pSink)
       at System.Management.SinkForEventQuery.Cancel()
       at System.Management.ManagementEventWatcher.Stop()
       at System.Management.ManagementEventWatcher.Finalize()
  InnerException: 

这是我得到的带有异常消息的窗口:

我还不知道有时什么是空的?为什么?以及如何解决。

【问题讨论】:

  • 您将无法轻松捕获此异常,因为它发生在 ManagementEventWatcher 的终结器中。此方法由 .NET 垃圾收集器在对对象的所有引用被删除后调用。您可能可以通过始终确保在退出之前有Stopped 观察者来避免这种情况。
  • 出现问题是因为您没有干净地处置观察者。在您的 StartWatching() 中,只需在第一行调用 StopWatching()。

标签: c# .net winforms


【解决方案1】:
    public static void StartWatching()
    {
        StopWatching(); //add this line
        try
        {
            WqlEventQuery query = new WqlEventQuery("Select * From __InstanceCreationEvent Within 2 Where TargetInstance Isa 'Win32_Process'");
            watcher = new ManagementEventWatcher(query);
            watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
            watcher.Start();
        }
        catch (Exception err)
        {
            string t = "err " + err.ToString();
        }
    }

您的问题出现是因为您创建了多个 EventWatcher 而没有清理旧的。如果您进行我建议的 1 行更改,您应该不会再遇到问题了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多