C#.NET监控进程

3
我们有一个第三方应用程序存在问题,需要在Citrix环境中监控并在必要时终止该进程。目前只能通过轮询的方式来实现,但这种方法不够优雅,需要使用定时任务。我希望能够编写一个服务来监控并检测该进程,如果运行时间过长,则杀死它。因此,我在Visual Studio中启动了一个Windows服务项目,并找到了this code from CodeProject,该代码使用ManagementEventWatcher注册WMI。
        string pol = "2";
        string appName = "MyApplicationName";

        string queryString =
            "SELECT *" +
            "  FROM __InstanceOperationEvent " +
            "WITHIN  " + pol +
            " WHERE TargetInstance ISA 'Win32_Process' " +
            "   AND TargetInstance.Name = '" + appName + "'";

        // You could replace the dot by a machine name to watch to that machine
        string scope = @"\\.\root\CIMV2";

        // create the watcher and start to listen
        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
        watcher.EventArrived += new EventArrivedEventHandler(this.OnEventArrived);
        watcher.Start();

这段代码的问题在于它说“this.OnEventArrived”的地方,我遇到了以下错误:
错误1:'MyServiceApp.Service1'不包含对'OnEventArrived'的定义,也没有接受类型为'MyServiceApp.Service1'的第一个参数的扩展方法'OnEventArrived'可以找到(您是否缺少使用指令或程序集引用?)
怎么回事?

1
你是否已经定义了你要订阅事件EventArrived的事件处理程序/回调方法this.OnEventArrived?它有什么签名? - stakx - no longer contributing
哇,我一点都不知道。显然不是,但我不确定该怎么做才能实现。我猜我需要编写一个名为"OnEventArrived"的方法,在事件到达时运行它?我甚至不确定它需要什么参数。那篇CodeProject文章甚至没有提到这一点。 - Nathan McKaskle
你现在找到了好的答案,但我建议你花点时间学习C#委托和事件。这种情况会经常出现。 - stakx - no longer contributing
1个回答

4

这方面的文档可以在MSDN上找到https://msdn.microsoft.com/zh-cn/library/system.management.managementeventwatcher.eventarrived%28v=vs.110%29.aspx

OnEventArrived应该是这个样子的。

private void OnEventArrived(object sender, ManagementEventArgs args)
{
//do your work here
}

这是一个监控记事本的示例程序。您可能希望阅读更多关于WMI的内容,以查看是否有更好的方法。您可以通过开始菜单启动记事本,并将Notepad启动输出到控制台。退出时,它将打印Notepad Exited。我不知道所有可能输出的消息。
    static void Main(string[] args)
    {

        string pol = "2";
        string appName = "Notepad.exe";

        string queryString =
            "SELECT *" +
            "  FROM __InstanceOperationEvent " +
            "WITHIN  " + pol +
            " WHERE TargetInstance ISA 'Win32_Process' " +
            "   AND TargetInstance.Name = '" + appName + "'";

        // You could replace the dot by a machine name to watch to that machine
        string scope = @"\\.\root\CIMV2";

        // create the watcher and start to listen
        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
        watcher.EventArrived += new EventArrivedEventHandler(OnEventArrived);
        watcher.Start();
        Console.Read();
    }

    private static void OnEventArrived(object sender, EventArrivedEventArgs e)
    {
        if (e.NewEvent.ClassPath.ClassName.Contains("InstanceCreationEvent"))
            Console.WriteLine("Notepad started");
        else if (e.NewEvent.ClassPath.ClassName.Contains("InstanceDeletionEvent"))
            Console.WriteLine("Notepad Exited");
        else
            Console.WriteLine(e.NewEvent.ClassPath.ClassName);
    }

我刚刚也弄清楚了,但问题是,在那里要写什么代码呢?他在那个codeproject页面上有一些关于记事本的混乱代码,但它不起作用,因为我找不到“ProcessInfo”类。比如,如果我将应用程序设置为notepad.exe,那么如果我启动记事本,我想测试一下MessageBox.Show("Notepad Opened");。 - Nathan McKaskle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接