【问题标题】:Exit all instances of my app退出我的应用程序的所有实例
【发布时间】:2012-10-23 08:26:18
【问题描述】:

我有以下功能:

private void TakeOverAllScreens()
    {
        int i = 0;
        foreach (Screen s in Screen.AllScreens)
        {

            if (s != Screen.PrimaryScreen)
            {
                i++;
               Process.Start(Application.ExecutablePath, "Screen|" + s.Bounds.X + "|" + s.Bounds.Y + "|" + i);
            }
        }
    }

如您所见,它为 pc 上的每个屏幕创建了我的应用程序的单独实例。

如何创建一个关闭所有这些的退出函数? 该函数需要适用于应用程序的任何实例,而不仅仅是我的“主”实例。

【问题讨论】:

  • Process 类有一个Id,你可以用它来杀死进程。

标签: c# winforms


【解决方案1】:

你可以终止所有同名的进程:

var current = Process.GetCurrentProcess();
Process.GetProcessesByName(current.ProcessName)
    .Where(t => t.Id != current.Id)
    .ToList()
    .ForEach(t => t.Kill());

current.Kill();

【讨论】:

  • 这是我使用的代码。奇迹般有效。但不是在调试中,因为ProcessName在调试中是不同的
【解决方案2】:

只需要跟踪打开的进程即可:

List<Process> opened = new List<Process>();

private void TakeOverAllScreens()
    {
        int i = 0;
        foreach (Screen s in Screen.AllScreens)
        {

            if (s != Screen.PrimaryScreen)
            {
                i++;
               opened.Add(Process.Start(Application.ExecutablePath, "Screen|" + s.Bounds.X + "|" + s.Bounds.Y + "|" + i));
            }
        }
    }

然后:

private void terminateAll()
{
      foreach (var p in opened) p.Kill();
}

【讨论】:

  • 这是否适用于应用程序的任何实例,还是仅适用于“主”实例?
  • 让我问一下新实例是否会递归地生成新实例?
  • 不,只有主实例创建新实例。
  • 是的。它应该通过“主”进程终止所有启动的进程。对于主进程,您可以使用Application.Exit() 终止它
【解决方案3】:

如何关闭应用程序?

共有三个常规选项:

  • 彻底杀死它
  • 假设它有一个主窗口并且它的行为是常规的,通过 P/Invoking SendMessage 向该窗口发送一个 WM_CLOSE 消息
  • 假设它想合作,使用自定义通信通道告诉它自己终止

您应该如何关闭应用程序?

彻底终止进程是一种严厉的做法,除非您知道该进程在终止时不会做任何敏感的事情,否则绝不应尝试这样做。通常这是最后的手段。

告诉它关闭其主窗口需要您首先了解该窗口的HWND 是什么;您可以通过遍历顶级窗口列表或让生成的进程以某种方式将其传达给您来做到这一点。它还假设当您要求关闭其主窗口时,另一个进程将决定自行终止(实际上它可以决定做任何事情,包括完全忽略该消息)。这种方法是一种合理的首次尝试,它通常适用于不受您控制的进程——尽管您必须自己找到窗口。

使用自定义通信通道可以让您完全控制发生的事情以及如何以多种方式实现它,但这种方法涉及编写最多的代码并且需要您对两个应用程序都有源代码访问权限。

结论

视情况而定。如果您 1000% 确定终止进程不会破坏任何内容,那么这将是一个快速而肮脏的解决方案;否则你需要使用两种“礼貌”方法之一。

【讨论】:

  • 该应用程序只读取和显示数据,所以杀死它很酷。此外,我是快速和肮脏的粉丝!
【解决方案4】:

将所有打开的进程放入列表中,这样你就可以一个一个地杀死进程。看下面的代码:

private void TakeOverAllScreens()
{
    int i = 0;
    List<Process> allProcesses = new List<Process>();
    foreach (Screen s in Screen.AllScreens)
    {
        if (s != Screen.PrimaryScreen)
        {
            i++;
           allProcesses.Add(Process.Start(Application.ExecutablePath, "Screen|" + s.Bounds.X + "|" + s.Bounds.Y + "|" + i));
        }
    }

    foreach (Process proc in allProcesses)
    {
        proc.Kill();
    }
}

【讨论】:

    【解决方案5】:

    我总是执行命令

    tskill notepad // to kill all instances of notepad
    

    在 App 内部,可以像这样完成

    Process.Start("cmd /k tskill " + Process.GetCurrentProcess().ProcessName)
    

    【讨论】:

      【解决方案6】:

      试试这个功能:

      void ExitAll(string processName)
      {
          foreach(Process p in Process.GetProcesses())
          {
              if (p.ProcessName.ToLower().Equals(processName.ToLower()))
                  p.Kill();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多