C# 程序单一进程化与实现程序重启的冲突问题

C# 程序单一进程化与实现程序重启的冲突问题


思路借鉴

需求描述:

  1. 程序运行过程中,不能有多个实例运行,进程唯一SingletonProcess
  2. 程序自己可以重启(重新运行),或者发生网络错误等严重错误时,程序重新启动,回到登录自检前的状态

需求分析:

程序重新启动时,需要先启动一个新的Process,然后再退出当前程序。
这样便与在Program.cs里遇到禁止多重启动的逻辑冲突。代码如下:

Process.Start(Process.GetCurrentProcess().ProcessName + ".exe");
Application.Exit();

解决方案

  1. 解决方案一:借助另一个程序实现重启功能(具体过程略)
  2. 解决方案二:重新启动时传递一个参数,用以表示目前需要执行重启逻辑,绕过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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值