I wrote a program in c# now I would like to know what is the proper way to prevent the program from starting if it is already running?
so if it is already running开发者_运维百科, and double-click on the program it will not start because it is already running.
I can do that, but I was thinking of a standard and proper way.
The recommended way to do this is with a system mutex.
bool createdNew;
using(var mutex = new System.Threading.Mutex(true, "MyAppName", out createdNew))
{
if (createdNew)
// first instance
Application.Run();
else
MessageBox.Show("There is already an instace running");
}
The first parameter to the Mutex ctor tells it to give create a system wide mutex for this thread. If the Mutex already exists it will return out false
through the 3rd parameter.
Update
Where to put this?
I'd put this in program.cs. If you put it in form_load you'll need to keep the mutex for the life time of the application (have the mutex as a member on the form), and manually release it in the form unload.
The earlier you call this the better, before the other app opens DB connections etc. and before resources are put created for forms / controlls etc.
Quick way I did in one of the applications .. You can look at the list of running processes to see whether the current application is already running and not start the application again.
Process[] lprcTestApp = Process.GetProcessesByName("TestApplication");
if (lprcTestApp.Length > 0)
{
// The TestApplication is already running, don't run it again
}
I think enumerating the process list could potentially be slow. You could also create a Mutex using the System.Threading.Mutex class and check to see if it's already created when the process starts. However, this would require calling into Win32 system code so wouldn't be completely platform agnostic.
Take a look at Scotts blog post and don't be foolished by the assembly name. It's just a file name of a standard file in the .Net framework.
Here are more informations direct out of MSDN for the WindowsFormsApplicationBase.
You can use a system-wide Semaphore, using the Semaphore Constructor (Int32, Int32, String, Boolean%) constructor and a fairly unique name.
Cheers, Matthias
If your application produces/consumes files, then you're better registering a system wide communication mechanism (e.g. a remoting or WCF endpoint, or even a socket). Then, if the second instance of the application is being launched from double clicking one of your files, you can send the file information across to the running instance.
Otherwise, if it's a standalone program, then as others have said, a Mutex or Semaphore would server equally well.
solution in Windows form application Prohibit again run application(reopen application).
1- first add Class RunAlready.cs
2-Call method processIsRunning() with Name Process from RunAlready.cs in Program.cs
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Tirage.MainStand
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
PublicClass.Class.RunAlready RunAPP = new PublicClass.Class.RunAlready();
string outApp = RunAPP.processIsRunning("Tirage.MainStand");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainStand_FrmLogin fLogin = new MainStand_FrmLogin();
if (outApp.Length == 0)
{
if (fLogin.ShowDialog() == DialogResult.OK)
{
Application.Run(new MainStand_masterFrm());
}
}
else MessageBox.Show( "Instance already running");
}
}
}
class RunAlready:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PublicClass.Class
{
public class RunAlready
{
public string processIsRunning(string process)
{
string xdescription = "";
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName(process);
foreach (System.Diagnostics.Process proc in processes)
{
var iddd = System.Diagnostics.Process.GetCurrentProcess().Id;
if (proc.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
{
xdescription = "Application Run At time:" + proc.StartTime.ToString() + System.Environment.NewLine;
xdescription += "Current physical memory : " + proc.WorkingSet64.ToString() + System.Environment.NewLine;
xdescription += "Total processor time : " + proc.TotalProcessorTime.ToString() + System.Environment.NewLine;
xdescription += "Virtual memory size : " + proc.VirtualMemorySize64.ToString() + System.Environment.NewLine;
}
}
return xdescription;
}
}
}
精彩评论