# C# 程序单一进程化与实现程序重启的冲突问题 #
C# 程序单一进程化与实现程序重启的冲突问题
思路借鉴
需求描述:
- 程序运行过程中,不能有多个实例运行,进程唯一SingletonProcess
- 程序自己可以重启(重新运行),或者发生网络错误等严重错误时,程序重新启动,回到登录自检前的状态
需求分析:
程序重新启动时,需要先启动一个新的Process,然后再退出当前程序。
这样便与在Program.cs里遇到禁止多重启动的逻辑冲突。代码如下:
重启代码
Process.Start(Process.GetCurrentProcess().ProcessName + ".exe"); Application.Exit();解决方案
- 解决方案一:借助另一个程序实现重启功能(具体过程略)
- 解决方案二:重新启动时传递一个参数,用以表示目前需要执行重启逻辑,绕过SingletonProcess判断以此达到重启目的
程序重启函数
程序重启函数
public static void RestartProgram()
{
//释放资源
//释放资源
//释放资源
System.Diagnostics.Process.Start(Application.ExecutablePath, "false");
System.Threading.Thread.Sleep(300);
//这里暴力杀死进程,不建议
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
完整代码Program.cs
static class Program { static readonly CommonLogger.Logger logger = new CommonLogger.Logger(typeof(Program)); public static bool createNew = true; [STAThread] static void Main(string[] str) { if (str != null && str.Length > 0) { if (str[0].Equals("false")) { createNew = false; } else { createNew = true; } } else { createNew = true; } using (System.Threading.Mutex m = new System.Threading.Mutex(true, Application.ProductName/*,out xxx*/)) { try { if (createNew) { Process instance = RunningInstance(); if (instance == null) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FrmLoading()); } else { HandleRunningInstance(instance); } } else { //重启时 //启动新的进程杀掉旧的进程 //并将重启标识复位 createNew = true; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FrmLoading()); } } catch (Exception e) { logger.Error("" + e); } } logger.Info("STAThread Main End " + GlobalInfo.MianID); //单一逻辑时会执行到此处,确保新的进程没有启动,也不存在资源占用的后台进程 Environment.Exit(0); } #region 进程唯一
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
private static void HandleRunningInstance(Process instance)
{
// 确保窗口没有被最小化或最大化
// ShowWindowAsync(instance.MainWindowHandle, 4);
ShowWindowAsync(instance.MainWindowHandle, 4);
// 设置真实例程为foreground window
SetForegroundWindow(instance.MainWindowHandle);// 放到最前端
}
private static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
if (process.Id != current.Id)
{
// 确保例程从EXE文件运行
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
{
return process;
}
}
}
return null;
}
#endregion
}

浙公网安备 33010602011771号