C# 监视 exe 何时启动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/967646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:26:36  来源:igfitidea点击:

Monitor when an exe is launched

c#.netwindows-servicesmonitoring

提问by

I have some services that an application needs running in order for some of the app's features to work. I would like to enable the option to only start the external Windows services to initialize after the application is launched. (as opposed to having them start automatically with the machine and take up memory when the application is not needed)

我有一些应用程序需要运行的服务才能使应用程序的某些功能正常工作。我想启用仅在应用程序启动后启动外部 Windows 服务进行初始化的选项。(而不是让它们随机器自动启动并在不需要应用程序时占用内存)

I do not have access to the exe's code to implement this, so ideally I would like to write a C# .Net Windows service that would monitor when an exe is launched.

我无权访问 exe 的代码来实现这一点,所以理想情况下我想编写一个 C# .Net Windows 服务来监视 exe 何时启动。

What I've found so far is the System.IO.FileSystemEventHandler. This component only handles changed, created, deleted, and renamed event types. I don't expect that a file system component would be the ideal place to find what I'm looking for, but don't know where else to go.

到目前为止我发现的是 System.IO.FileSystemEventHandler。此组件仅处理更改、创建、删除和重命名的事件类型。我不希望文件系统组件是找到我正在寻找的东西的理想场所,但不知道还能去哪里。

Maybe I'm not searching with the right keywords, but I have not yet found anything extremely helpful on Google or here on stackoverflow.com.

也许我没有使用正确的关键字进行搜索,但我还没有在 Google 或 stackoverflow.com 上找到任何非常有用的东西。

The solution would be required to run on XP, Vista, and Win 7 when it comes...

该解决方案需要在 XP、Vista 和 Win 7 上运行时...

Thanks in advance for any pointers.

在此先感谢您的指点。

采纳答案by Michael Petrotta

From this article, you can use WMI (the System.Managementnamespace) in your service to watch for process start events.

本文中,您可以System.Management在服务中使用 WMI(命名空间)来监视进程启动事件。

 void WaitForProcess()
{
    ManagementEventWatcher startWatch = new ManagementEventWatcher(
      new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
    startWatch.EventArrived
                        += new EventArrivedEventHandler(startWatch_EventArrived);
    startWatch.Start();

    ManagementEventWatcher stopWatch = new ManagementEventWatcher(
      new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"));
    stopWatch.EventArrived
                        += new EventArrivedEventHandler(stopWatch_EventArrived);
    stopWatch.Start();
}

  static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) {
    stopWatch.Stop();
    Console.WriteLine("Process stopped: {0}"
                      , e.NewEvent.Properties["ProcessName"].Value);
  }

  static void startWatch_EventArrived(object sender, EventArrivedEventArgs e) {
    startWatch.Stop();
    Console.WriteLine("Process started: {0}"
                      , e.NewEvent.Properties["ProcessName"].Value);
  }
}

WMI allows for fairly sophisticated queries; you can modify the queries here to trigger your event handler only when your watched app launches, or on other criteria. Here's a quick introduction, from a C# perspective.

WMI 允许相当复杂的查询;您可以修改此处的查询以仅在您观看的应用程序启动时或根据其他条件触发您的事件处理程序。 这是从 C# 角度的快速介绍

回答by Sam Saffron

you have 3 options here:

您在这里有 3 个选择:

The reliable/intrusive one, set up a hook in unmanaged code that communicates back to your C# app whenever an app is launched. This is hard to get right and involves loading an extra DLL with each process. (Alternatively you could set up a driver, which is even harder to write)

可靠的/侵入式的,在非托管代码中设置一个钩子,每当一个应用程序启动时,它就会与你的 C# 应用程序通信。这很难做到正确,并且涉及为每个进程加载一个额外的 DLL。(或者你可以设置一个驱动程序,这更难写)

The less reliable way, list all the processes (using the System.Diagnostics.Processclass) on a regular basis (say every 10-30 secs) to see if the app is launched.

不太可靠的方法是,定期(例如每 10-30 秒)列出所有进程(使用System.Diagnostics.Process类)以查看应用程序是否已启动。

It also may be possible to watch the Win32_Process, InstanceCreationEvent WMI event from managed code. Not sure how reliable this is, but I suspect it would be better than polling processes.

也可以从托管代码中观察 Win32_Process、InstanceCreationEvent WMI 事件。不确定这有多可靠,但我怀疑它会比轮询过程更好。

回答by devdimi

Monitor if the process is running - one service must be running to do this though.

监视进程是否正在运行 - 但是必须运行一项服务才能执行此操作。

If you really don't want to consume any ressources - write a simple service in plain C. Service application written without MFC/ATL can consume as low as 300-400 kb memory and virutally no CPU cycles. When the process you are interested in starts you can spawn your C# services.

如果你真的不想消耗任何资源 - 用纯 C 编写一个简单的服务。没有 MFC/ATL 编写的服务应用程序可以消耗低至 300-400 kb 的内存,并且几乎没有 CPU 周期。当您感兴趣的进程开始时,您可以生成您的 C# 服务。

回答by lankitha

 public Process IsProcessOpen(string name)
        {
            foreach (Process clsProcess in Process.GetProcesses())
                if (clsProcess.ProcessName.Contains(name))
                    return clsProcess;
            return null;
        }

回答by Jan S

In reply to the Windows 7 aspect of it not working. If you are monitoring 64 bit processes your process needs to be built to work in the 64bit address space too.

回复 Windows 7 方面它不起作用。如果您正在监视 64 位进程,您的进程也需要构建为在 64 位地址空间中工作。