所以这段代码在program.cs中,并且应该检查连接是否可用以及是否有另一个实例已经运行。如果有,则消息框通知用户,并询问他是否确定要打开该应用程序。问题是下一个: 我打开应用程序,然后再次打开它,消息框显示但没有任何反应。我重复这个过程,只有4-5次才有效。然后,如果我再次打开,它会打开2个实例。
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SqlConnection con123 = new SqlConnection(con123.Metoda());
Mutex mut = null;
try
{
mut = Mutex.OpenExisting("Tray minimizer");
}
catch
{
}
if (mut == null)
{
mut = new Mutex(true, "Tray minimizer");
Application.Run(new Form1());
//Tell GC not to destroy mutex until the application is running and
//release the mutex when application exits.
GC.KeepAlive(mut);
mut.ReleaseMutex();
}
else
{
//The mutex existed so exit
mut.Close();
DialogResult result = MessageBox.Show("AApplication is already working!Do you want to reopen it?", "Caution!", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName("Name of application"))
{
try
{
p.Kill();
// p.WaitForExit(); // possibly with a timeout
Application.Run(new Form1());
}
catch (Win32Exception winException)
{
// process was terminating or can't be terminated - deal with it
}
catch (InvalidOperationException invalidException)
{
// process has already exited - might be able to let this one go
}
}
}
//if (result == DialogResult.Cancel)
//{
//}
}
try
{
con123.Open();
con123.Close();
}
catch
{
MessageBox.Show("Cant connect to server!!!", "Error!");
Application.Exit();
}
答案 0 :(得分:1)
我会做更多的事情:
bool mutexCreated = true;
using (Mutex mutex = new Mutex(true, "eCS", out mutexCreated))
{
if (mutexCreated)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SqlConnection con123 = new SqlConnection(con123.Metoda());
Application.Run(new Form1());
}
else
{
DialogResult result =
MessageBox.Show("AApplication is already working!Do you want to reopen it?", "Caution!",
MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName("Name of application"))
{
try
{
p.Kill();
Application.Run(new Form1());
}
catch (Win32Exception winException)
{
// process was terminating or can't be terminated - deal with it
}
catch (InvalidOperationException invalidException)
{
// process has already exited - might be able to let this one go
}
}
}
}
try
{
con123.Open();
con123.Close();
}
catch
{
MessageBox.Show("Cant connect to server!!!", "Error!");
Application.Exit();
}
}
您的版本存在的问题是可能会在不适当的时间收集互斥锁。
答案 1 :(得分:0)
一旦你进入“互斥锁存在”路径,就永远不会释放互斥锁。您只需删除任何其他进程并再次启动应用程序,但永远不会提供在新应用程序结束时释放互斥锁的方法。
您正在foreach (Process)
循环中启动您的应用,这意味着如果有多个进程已在运行(可能所有进程都带有消息框),您将为每个进程启动应用。
这也意味着如果您实际上没有找到另一个要杀死的进程,则无法启动您的应用。
您的else
案例看起来应该像这样的伪代码:
dialogResult = MessageBox(...);
if (dialogResult == OK)
{
foreach (var p in ...)
{
// Todo: make sure you do not kill the current process!
p.Kill();
}
// now run the application
Application.Run(new Form1());
// now release the mutex
mut.Release();
}
else
{
mut.Close();
}
伪代码仍需要一些异常处理,以确保在发生异常时正确释放互斥锁。
答案 2 :(得分:0)
这可以解决您的问题吗?我没有使用OpenExisting
,它没有保证在失败时返回null
的文档保证,而是使用Mutex
构造函数来获取out bool
来确定互斥锁是否已创建或者它是否已经存在。启动应用程序并对其执行任何操作(根据我所看到的内容进行部分猜测)将移至与创建互斥锁或关闭现有实例相关的所有内容之下。
现在步骤如下:
runApp
变量初始化为true Mutex
Mutex
是否已创建(尚未存在)
Mutex
,则它已存在
runApp
设为false
检查runApp
标志是否仍为真
如果确实如此,请运行该应用程序。返回后(表单退出),尝试连接
请注意,这可能有错误,我不知道您是否打算在应用中阻止。
释放互斥锁
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SqlConnection con123 = new SqlConnection(con123.Metoda());
string ProgramName = "Tray minimizer.exe";
bool mutCreated = false;
Mutex mut = new Mutex(true, ProgramName, out mutCreated);
bool runApp = true;
if (!mutCreated)
{
DialogResult result = MessageBox.Show("Application is already working! Do you want to reopen it?", "Caution!", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName(ProgramName))
{
try
{
p.Kill();
}
catch { }
}
mut.WaitOne(); // Wait for ownership of the mutex to be released when the OS cleans up after the process being killed
}
else
{
runApp = false;
}
}
if (runApp)
{
Application.Run(new Form1());
try
{
con123.Open();
con123.Close();
}
catch
{
MessageBox.Show("Cant connect to server!!!", "Error!");
Application.Exit();
}
mut.ReleaseMutex();
}