0

我无法在 Visual C# 中创建一个简单的应用程序,该应用程序执行以下操作:

  1. 坚持寻求一个具体的过程。
  2. 当该进程开始运行时,将资源复制到文件夹中。
  3. 当该过程结束时,将另一个资源复制到该文件夹​​。

我尝试使用计时器+线程,但没有成功。我认为 BackgroundWorker 在这里会有所帮助,但文档还不清楚。这是我当前的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ResourceCopyApp
{
    public partial class MainWindow : Window {
        BackgroundWorker bw;
        bool pcRunning = false;
        public MainWindow() {
            InitializeComponent();
            bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(Loop);
            bw.RunWorkerAsync();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e) {
            cfgInstall.Text = Properties.Settings.Default.pcLocation;
            cfgLag.Value = Properties.Settings.Default.lag;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
            Properties.Settings.Default.pcLocation = cfgInstall.Text;
            Properties.Settings.Default.lag = (int)cfgLag.Value;
            Properties.Settings.Default.Save();
        }

        public void Loop(object sender, DoWorkEventArgs e) {
            pcRunning = false;
            bool pcWasRunning = pcRunning;
            if (pcRunning && !pcWasRunning) {
                MessageBox.Show("Process found");
                pcWasRunning = true;
                Swap(true);
            }
            foreach (Process p in Process.GetProcesses()) {
                if (p.ProcessName.Equals("Process")) {
                    pcRunning = true;
                }
            }
            if (!pcRunning && pcWasRunning) {
                MessageBox.Show("Process lost");
                Swap(false);
            }
        }
        public void Swap(bool v) {
            byte[] file;
            Thread.Sleep(new TimeSpan((long)cfgLag.Value));
            if (v) {
                file = Properties.Resources.NewRes;
            } else {
                file = Properties.Resources.BackupRes;
            }
            string path = cfgInstall.Text;
            if (!cfgInstall.Text.EndsWith("/") && !cfgInstall.Text.EndsWith("\\")) {
                path = cfgInstall.Text + "/test.txt";
            }
            File.WriteAllBytes(path, file);

        }
    }
}
4

1 回答 1

1

正如我在评论中提到的,您当前的代码只运行一次检查,然后 BackgroundWorker 完成。您可以:

  • 使用计时器间歇性地(比如每分钟)查找进程,按照您当前在Loop. 当进程开始时,您可以使用Process.WaitForExit()暂停代码直到进程完成。要继续让您的程序响应,这部分应该在BackgroundWorker. 当然,这种方法存在一个风险,即进程在计时器滴答之间快速启动和完成。

  • ManagementEventWatcher在 WMI 中使用。CodeProject 上的这篇文章定义了一个类,该类简化了使用 WMI 在进程启动和停止时收到通知:

    notePad = new ProcessInfo("notepad.exe");
    notePad.Started +=
        new Win32Process.ProcessInfo.StartedEventHandler(this.NotepadStarted);
    notePad.Terminated +=
        new Win32Process.ProcessInfo.TerminatedEventHandler(this.NotepadTerminated);
    

他们使用的底层代码如下:

  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
  watcher = new ManagementEventWatcher(scope, queryString);
  watcher.EventArrived +=
          new EventArrivedEventHandler(this.OnEventArrived);
  watcher.Start();
于 2012-07-04T23:56:10.607 回答