当我调用Application.Restart()方法时,会出现错误,检测应用程序当前是否正在运行。反正有吗?
static void Main(string[] args)
{
string proc = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(proc);
if (processes.Length > 1)
{
MessageBox.Show("Program is already running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
答案 0 :(得分:3)
使用互斥锁。例如:A Single Instance Application which Minimizes to the System Tray when Closed。此示例比您可能需要的更复杂,但使用Mutex的基本单实例概念运行良好。
答案 1 :(得分:1)
执行此操作的最有效方法是从VB.Net的WindowsFormsApplicationBase
类继承,该类也可以在C#中使用,并将IsSingleInstance
属性设置为true
。这使用互斥锁,如果重命名EXE文件,它将继续工作。
答案 2 :(得分:1)
我有一个类似的问题,但我的是与无法管理的内存泄漏有关,我无法在一个必须全天候运行的应用程序上找到。对于客户,我同意如果内存消耗超过定义值,则重启应用程序的安全时间是03:00 AM。
我尝试Application.Restart
,但由于它似乎使用某种机制在它已经运行时启动新实例,我去了另一个方案。我使用了文件系统处理的技巧,直到创建它们的进程死掉。因此,从应用程序中,我将文件删除到磁盘,并没有Dispose()
句柄。我使用该文件发送'我自己'的可执行文件和启动目录(以增加灵活性)。
代码:
_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
WorkingDirectory = Application.StartupPath,
Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();
最后 Close()
将启动应用程序关闭,我在此处用于StreamWriter
的文件句柄将保持打开状态,直到进程真正死亡。然后...
Restarter.exe开始运行。它试图以独占模式读取文件,阻止它在主应用程序没有死之前获得访问权限,然后启动主应用程序,删除文件并存在。我想这不可能更简单:
static void Main(string[] args)
{
string filename = args[0];
DateTime start = DateTime.Now;
bool done = false;
while ((DateTime.Now - start).TotalSeconds < 30 && !done)
{
try
{
StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
string[] runData = new string[2];
runData[0] = sr.ReadLine();
runData[1] = sr.ReadLine();
Thread.Sleep(1000);
Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
sr.Dispose();
File.Delete(filename);
done = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(1000);
}
}
答案 3 :(得分:0)
最简单的方法是在退出前添加延迟。
换句话说,
string proc = Process.GetCurrentProcess().ProcessName;
if (Process.GetProcessesByName(proc).Length > 1) {
Thread.Sleep(500); //500 milliseconds; you might need to wait longer
if (Process.GetProcessesByName(proc).Length > 1) {
MessageBox.Show("Program is already running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} //no else
答案 4 :(得分:0)
尝试将重启代码作为侦听器方法连接到Application.ApplicationExit事件。然后,您将调用Application.Exit以使代码间接运行。
修改:添加了代码示例:
例如,当用户单击“重启”按钮或应用程序决定重新启动时,请调用此RestartMeSmartly()方法。你不必担心欺骗 - 它会起作用。
void RestartMeSmartly() {
Application.ApplicationExit += BeforeExiting;
Application.Exit();
}
void BeforeExiting(object sender, EventArgs args) {
Application.Restart();
}