Возможный дубликат:
Каков правильный способ создания одного экземпляра приложения?
Как заставить приложение С#.net запускать только один экземпляр в Windows?
Возможный дубликат:
Каков правильный способ создания одного экземпляра приложения?
Как заставить приложение С#.net запускать только один экземпляр в Windows?
Я предпочитаю решение мьютекса, подобное следующему. Таким образом, он снова фокусируется на приложении, если он уже загружен.
using System.Threading;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool createdNew = true;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
{
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
SetForegroundWindow(process.MainWindowHandle);
break;
}
}
}
}
}
чтобы принудительно запустить только один экземпляр программы в .net(С#), используйте этот код в файле program.cs:
public static Process PriorProcess()
// Returns a System.Diagnostics.Process pointing to
// a pre-existing process with the same name as the
// current one, if any; or null if the current process
// is unique.
{
Process curr = Process.GetCurrentProcess();
Process[] procs = Process.GetProcessesByName(curr.ProcessName);
foreach (Process p in procs)
{
if ((p.Id != curr.Id) &&
(p.MainModule.FileName == curr.MainModule.FileName))
return p;
}
return null;
}
и следующим образом:
[STAThread]
static void Main()
{
if (PriorProcess() != null)
{
MessageBox.Show("Another instance of the app is already running.");
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
Это то, что я использую в своем приложении:
static void Main()
{
bool mutexCreated = false;
System.Threading.Mutex mutex = new System.Threading.Mutex( true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated );
if( !mutexCreated )
{
if( MessageBox.Show(
"slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?",
"slimKEYS already running",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question ) != DialogResult.Yes )
{
mutex.Close();
return;
}
}
// The usual stuff with Application.Run()
mutex.Close();
}
другой способ для одного экземпляра приложения - проверить свои хэш-суммы. после беспорядка с мьютексом (не работает, как я хочу), я получил его работу следующим образом:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public Main()
{
InitializeComponent();
Process current = Process.GetCurrentProcess();
string currentmd5 = md5hash(current.MainModule.FileName);
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
if (process.Id != current.Id)
{
try
{
if (currentmd5 == md5hash(process.MainModule.FileName))
{
SetForegroundWindow(process.MainWindowHandle);
Environment.Exit(0);
}
}
catch (/* your exception */) { /* your exception goes here */ }
}
}
}
private string md5hash(string file)
{
string check;
using (FileStream FileCheck = File.OpenRead(file))
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] md5Hash = md5.ComputeHash(FileCheck);
check = BitConverter.ToString(md5Hash).Replace("-", "").ToLower();
}
return check;
}
он проверяет только суммы md5 по идентификатору процесса.
если экземпляр этого приложения был найден, он фокусирует запущенное приложение и выходит из него.
вы можете переименовать его или сделать то, что хотите с вашим файлом. он не будет открываться дважды, если хеш md5 тот же.
Может у кого-то есть предложения? я знаю, что это ответ, но, возможно, кто-то ищет альтернативу мьютексом.