SoFunction
Updated on 2025-03-06

Methods in C# programming that set the program to be run only once

There are many ways to prevent a program from running multiple instances, such as: by using mutexes and process names. What I want to achieve is: when the program runs multiple instances, the first instance is activated to get focus and display it on the front end.

Two API functions are mainly used:

ShowWindowAsync This function sets the display status of windows generated by different threads.
SetForegroundWindow This function sets the thread that creates the specified window to the foreground and activates the window. Keyboard input turns to this window and changes various visual marks to the user. The system assigns permissions to threads that create the foreground window slightly higher than other threads.
The code is as follows:
Reference to the following namespace:

using ;
using ;
using ;
//*****************************************************
 static class Program
  {
    /// <summary>
    /// This function sets the display status of the window generated by different threads.    /// </summary>
    /// <param name="hWnd">Window handle</param>    /// <param name="cmdShow">Specify how the window is displayed.  To view the list of allowed values, please refer to the description section of the ShowWlndow function.  </param>    /// <returns> If the function is originally visible, the return value is non-zero; if the function is originally hidden, the return value is zero.  </returns>    [DllImport("")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
    /// &lt;summary&gt;
    /// This function sets the thread that creates the specified window to the foreground and activates the window.  Keyboard input turns to this window and changes various visual marks to the user.  The system assigns permissions to threads that create the foreground window slightly higher than other threads.    /// &lt;/summary&gt;
    /// <param name="hWnd"> will be activated and transferred to the foreground window handle.  </param>    /// <returns> If the window is set to the foreground, the return value is non-zero; if the window is not set to the foreground, the return value is zero.  </returns>    [DllImport("")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    private const int WS_SHOWNORMAL = 1;

    /// &lt;summary&gt;
    /// The main entry point of the application.    /// &lt;/summary&gt;
    [STAThread]
    static void Main()
    {
      ();
      (false);
      Process instance = RunningInstance();
      if (instance == null)
      {
        Form1 frm = new Form1();
        (new Form1());
      }
      else
      {
        HandleRunningInstance(instance);
      }

    }
    /// &lt;summary&gt;
    /// Get the running instance, and the instance that has not run returns null;    /// &lt;/summary&gt;
    public static Process RunningInstance()
    {
      Process current = ();
      Process[] processes = ();
      foreach (Process process in processes)
      {
        if ( != )
        {
          if (().("/", "\\") == )
          {
            return process;
          }
        }
      }
      return null;
    }

    /// &lt;summary&gt;
    /// Shows the running program.    /// &lt;/summary&gt;
    public static void HandleRunningInstance(Process instance)
    {
      ShowWindowAsync(, WS_SHOWNORMAL); //Show, can be commented out      SetForegroundWindow();      //Put it to the front end    }
  }

Implementation allows the program to only open one instance (other methods)

//===== Create mutex method: ============bool blnIsRunning;
Mutex mutexApp = new Mutex(false, ().FullName, out  blnIsRunning);
if (!blnIsRunning)
{
  ("The program is running!", "hint",
  , );
  return;
}  



//Certify that only one client is running at the same time mutexMyapplication = new (false, "");
if (!(100, false))
{
  ("program" +  + "It's already running!", ,
  , );
  return;
}


//======Judge process method: (can still be executed after modifying the program name)=======Process current = ();
Process[] processes = ();
foreach (Process process in processes)
{
  if ( != )
  {
    if (
    == )
    {
      ("The program is running!", ,
      , );
      return;
    }
  }
}

Implement self-restarting of the program
During the program running, multiple instances cannot be run, and the program needs to restart (rerun) by itself, so if the code is as follows:

static void Main() 
{ 
  bool createNew; 
  using ( m = new (true, , out createNew)) 
  { 
    if (createNew) 
    { 
      (); 
      (false); 
      (new Form1()); 
    } 
    else 
    { 
      ("Only one instance of this application is allowed!"); 
    } 
  } 
}
Boolean createdNew; //Return whether the initial ownership of the mutex using the thread is given. instance = new (true, "MutexName", out createdNew); //Synchronous primitive variablesif (createdNew) //The thread is given initial ownership, that is, the first time using mutex{
(new Form1()); /s/This sentence is automatically written by the system
();
}
else
{
("A program has been started, please exit first!","System Prompt",,);
();
}

The above code is used to implement the function of prohibiting multiple startups.
At the same time, the program shutdown and restart is achieved through the following code:

(().ProcessName + ".exe");
();

At this time, a problem occurs. When the program is automatically closed and restarted, it will prompt that a program has been started.
How should I solve it?
It is OK to start again after shutting down.
But now it is automatically shut down. Automatic restart can sometimes succeed, and sometimes it is intercepted by the one that prohibits multiple startups.
Then you have to restart manually.
For example, when clicking the [Restart] button, execute the following code:

(().ProcessName + ".exe");
();

At this time, it starts a new Process before exiting the current program.
At this time, you will encounter the code that prohibits multiple startups. It cannot be started automatically.
Solution:
Solution 1:
General Procedure:
Because the process has not been aborted and still occupies memory, an error is reported.
This may occur because multithreading is used, where the threads do not end the execution and are not set as background threads, so although the application is closed, the process still resides in memory.
All threads in the process can be aborted using();.
You can also obtain the process ID during process execution, then obtain the process through(), then Kill it and start a new process.

Solution 2:
Or just release the mutex first when the user clicks [Restart]? You may need to make that mutex variable into a global so that you can access it in both places. Then when the program exits (the following sentence), check that if mutex has been released, don't release it again.

Solution three:
Or set another different semaphore when clicking [Restart]. When the second program reenters, if you see that this semaphore is automatically restarted, you will go down normally without an error. This semaphore can be released after execution in the first program [restart], but it should also be checked when the entire program exits and releases if it exists.