简体   繁体   中英

Preventing a user from running more than one instance of a process

I am not an experienced programmer so any advice/guidance/examples would be appreciated! I have a windows form application in C# (.Net framework 4.5) that is replacing a windows service (issues with the Session0 variable were encountered). The application needs to open a process, (I'll be using Notepad as an example) and check every 5minutes whether Notepad is still open. If Notepad is not open, the form application must open an instance of it. The application must stop a user from opening another instance of Notepad, if it is already open. My coding currently closes all instances of Notepad. I simply need the application to stop a second instance of Notepad to be opened. The problem is that the user is not allowed to interact with the application at all, as you will note in the coding the user doesn't even see the form. Here is my coding thus far:

    private void Form1_Load(object sender, EventArgs e)
    {
        this.ShowInTaskbar = false;
        this.Visible = false;
        //handle Elapsed event
        myTimer.Tick += new EventHandler(OnElapsedTime);
        //This statement is used to set interval to 5 minute (= 300,000 milliseconds)
        myTimer.Interval = 60000;//300000;
        //enabling the timer
        myTimer.Enabled = true;
        WatchForProcessStart("Notepad.exe");
    }

     private void OnElapsedTime(object source, EventArgs e)
    {
        bool status = IsProcessOpen("notepad");
          if (status == true)
          {
              //TraceService("Notepad is already open" + DateTime.Now);
          }
          else
          {
            Process process = new Process();
            process.StartInfo.FileName = "notepad.exe";
            process.EnableRaisingEvents = true;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            process.Start();
            //TraceService("Notepad opened" + DateTime.Now);
          }
    }

     public bool IsProcessOpen(string procName)
     {
         System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName(procName);
         if (proc.Length > 0)
         {
             return true;
         }
         else
         {
             return false;
         }
     }

     private ManagementEventWatcher WatchForProcessStart(string processName)
     {
         string queryString =
             "SELECT TargetInstance" +
             "  FROM __InstanceCreationEvent " +
             "WITHIN  10 " +
             " WHERE TargetInstance ISA 'Win32_Process' " +
             "   AND TargetInstance.Name = '" + processName + "'";

         // The dot in the scope means use the current machine
         string scope = @"\\.\root\CIMV2";

         // Create a watcher and listen for events
         ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
         watcher.EventArrived += ProcessStarted;
         watcher.Start();
         return watcher;
     }

     private void ProcessStarted(object sender, EventArrivedEventArgs e)
     {
         ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
         string processName = targetInstance.Properties["Name"].Value.ToString();
         bool status = IsProcessOpen("notepad");
         if (status == true)
         {
             System.Diagnostics.Process.Start("cmd.exe", "/c taskkill /IM notepad.exe");
         }
         else
         {
             Process process = new Process();
             process.StartInfo.FileName = "notepad.exe";
             process.EnableRaisingEvents = true;
             process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
             process.Start();
         }
     }

Wrap it up in a Mutex

 var mutexId = "MyApplication";
 using (var mutex = new Mutex(false, mutexId))
 {
    if (!mutex.WaitOne(0, false))
    {
       MessageBox.Show("Only one instance of the application is allowed!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Hand);
       return;
    }
    // Do scome work
 }

If you want to restrict it to one instance per machine, the mutexId needs to be prefixed with Global\\

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM