【问题标题】:How do I restart a WPF application? [duplicate]如何重新启动 WPF 应用程序? [复制]
【发布时间】:2011-01-23 11:50:40
【问题描述】:

如何重新启动 WPF 应用程序? 在我使用的 windows 窗体中

System.Windows.Forms.Application.Restart();

如何在 WPF 中做到这一点?

【问题讨论】:

  • 可能的重复项:stackoverflow.com/questions/3895188/…stackoverflow.com/questions/1225406/…stackoverflow.com/questions/3634439/…。共识是 WinForms 方式没有完全相同的副本,并且所有“解决方案”都闻起来有点老套。我怀疑这是因为您通常不需要这样做,除非在调试期间。
  • @Cody Gray 现在我再次调用那些在应用程序之星上调用的方法。它运作良好。但对于其他应用程序,我必须重新启动应用程序。
  • @Cody Gray 你为什么说一个人永远不需要这个?可能需要重新启动应用程序的原因有很多,当您可以为他们执行此操作时,为什么还要强制用户重新运行可执行文件?
  • @epalm:就是这样:除了调试期间,我想不出一个应用程序可能需要重新启动的单一原因。 也许如果您已经自动下载并安装了更新,但这可能应该使用单独的更新程序完成,应该只在启动/关闭时发生,并且应该让用户决定是否需要继续在应用程序中工作(a la Firefox 和 Chrome)。
  • @Cody Gray - 这是一个例子(除非你能给我一个更好的方法来做到这一点)。我们正在运行一个使用 WPF 连接到服务器的应用程序。它发现服务器,然后使用该发现信息来编写客户端配置。该应用程序在重新启动之前无法使用此信息,因此在下载配置后,我们必须重新启动。

标签: c# .net wpf .net-4.0


【解决方案1】:

我发现了这个: 有用。 但。 有没有更好的办法?

System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();

【讨论】:

  • @AndreiRinea 不。但只需在开始时保存它们并将它们作为参数传递给此函数调用。这很容易。
  • 请注意,如果您的应用程序是使用 ClickOnce 部署的,则您不想使用此方法。 ApplicationDeployment.IsNetworkDeployed 将在您重新启动时为假。请参阅bit.ly/RKoVBz 了解更多信息。如果您的应用程序未使用 ClickOnce 部署,则此方法效果很好。
  • @blachniet 谢谢。记下了。
  • @ChristianMark,它可能没有效果。这取决于您的应用程序。我过去曾开发过一些应用程序,它们同时具有 ClickOnce 和普通安装程序部署,并且根据 ApplicationDeployment.IsNetworkDeployed 是否为真,它们中的某些部分的行为会有所不同。例如,如果您在组织内部署 ClickOnce,则您可能能够推断出您应该有权访问组织网络资源(文件共享、电子邮件服务器等)。
  • 如果你想保留命令行参数,你可以先从Environment.GetCommandLineArgs()获取它们,然后将它们传递给 Process.Start 方法
【解决方案2】:

我已经在 WPF 中成功使用了这个:

System.Windows.Forms.Application.Restart();
System.Windows.Application.Current.Shutdown();

【讨论】:

  • 我认为仅仅为此包含 WinForms 程序集参考有点矫枉过正。
  • @commanderz 我倾向于同意,但是我已经在同一个项目中使用了像 System.Windows.Forms.FolderBrowserDialog() 这样的 WinForms 魔法。
  • @MatějZábský 在使用 ClickOnce 时甚至是必要的。
  • 这是我发现重启 ClickOnce 应用程序的唯一方法。谢谢。
【解决方案3】:

延迟 1 秒后通过命令行运行程序的新实例。 在延迟当前实例关闭期间。

ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C choice /C Y /N /D Y /T 1 & START \"\" \"" + Assembly.GetEntryAssembly().Location + "\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
Process.GetCurrentProcess().Kill();

编辑:

我修复了代码:

而不是:Assembly.GetExecutingAssembly().Location

这个:Assembly.GetEntryAssembly().Location

当函数在单独的 dll 中运行时,这一点很重要。

还有-

而不是:Application.Current.Shutdown();

这个:Process.GetCurrentProcess().Kill();

它在 WinForms 和 WPF 中都可以工作,如果你编写一个为两者设计的 dll,那么它就非常重要了。

【讨论】:

    【解决方案4】:
    Application.Current.Shutdown();
    System.Windows.Forms.Application.Restart();
    

    按此顺序对我有用,反之则只是启动了应用程序的另一个实例。

    【讨论】:

    • 我不能确切地告诉你它为什么起作用,但只能告诉你它在 WPF 中起作用
    • 在 WinForms 中非常适合我!
    • 刚刚在 .NET 4.8 上使用我的 WPF 应用程序进行了尝试,它运行良好。 =]
    【解决方案5】:
    Application.Restart();
    

    System.Diagnostics.Process.Start(Application.ExecutablePath);
    Application.Exit();
    

    在我的程序中,我有一个互斥锁来确保只有一个应用程序实例在计算机上运行。这导致新启动的应用程序无法启动,因为互斥锁没有及时释放。结果,我在 Properties.Settings 中输入了一个值,表明应用程序正在重新启动。在调用 Application.Restart() 之前,将 Properties.Settings 值设置为 true。在 Program.Main() 中,我还添加了对该特定 property.settings 值的检查,以便在为 true 时将其重置为 false 并且存在 Thread.Sleep(3000);

    在你的程序中你可能有这样的逻辑:

    if (ShouldRestartApp)
    {
       Properties.Settings.Default.IsRestarting = true;
       Properties.Settings.Default.Save();
       Application.Restart();
    }
    

    在 Program.Main() 中

    [STAThread]
    static void Main()
    {
       Mutex runOnce = null;
    
       if (Properties.Settings.Default.IsRestarting)
       {
          Properties.Settings.Default.IsRestarting = false;
          Properties.Settings.Default.Save();
          Thread.Sleep(3000);
       }
    
       try
       {
          runOnce = new Mutex(true, "SOME_MUTEX_NAME");
    
          if (runOnce.WaitOne(TimeSpan.Zero))
          {
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new Form1());
          }
       }
       finally
       {
          if (null != runOnce)
             runOnce.Close();
       }
    }
    

    就是这样。

    【讨论】:

    • 这个答案(标记为答案)具有误导性。最初的问题是关于重新启动 WPF 应用程序,这与在 WinForms 中的完成方式非常相似。不幸的是,您的答案仍在使用 WinForms 重新启动(在 WPF 中不可用的东西),并且还包含与所问问题无关的示例(例如 Mutex?)。
    • 可能会误导 WPF-Only 答案,但与其他答案结合使用对我来说很有用,因为我需要重新启动使用互斥锁的 WPF。这样就可以了。
    【解决方案6】:

    这些提议的解决方案可能有效,但正如另一位评论者所提到的,它们感觉有点像快速破解。另一种感觉更简洁的方法是运行一个批处理文件,其中包含延迟(例如 5 秒)以等待当前(关闭)应用程序终止。

    这可以防止两个应用程序实例同时打开。在我的情况下,同时打开两个应用程序实例是无效的——我使用互斥锁来确保只有一个应用程序打开——因为应用程序使用了一些硬件资源。

    示例 windows 批处理文件(“restart.bat”):

    sleep 5
    start "" "C:\Dev\MyApplication.exe"
    

    并在 WPF 应用程序中,添加以下代码:

    // Launch the restart batch file
    Process.Start(@"C:\Dev\restart.bat");
    
    // Close the current application
    Application.Current.MainWindow.Close();
    

    【讨论】:

    • 写一个带睡眠的批处理文件感觉就像一个很长的黑客,但可能更糟。
    • @Philliproso 同意,这是一个 hack,当时我需要一个全新的 windows 进程来重新启动应用程序,我相信这里的其他方法不提供,但是这个提供。跨度>
    【解决方案7】:
     Application.Restart();
     Process.GetCurrentProcess().Kill();
    

    工作对我来说就像一个魅力

    【讨论】:

    • 这帮助我避免了一个简单的问题,我的启动参数,我的应用程序在我尝试的任何重启方法上都崩溃了,而这个方法保证了事情的安全。谢谢你:)
    • 从哪里重新启动? System.Windows.Application 没有 Restart 方法
    【解决方案8】:

    以 Hooch 为例,我使用了以下内容:

    using System.Runtime.CompilerServices;
    
    private void RestartMyApp([CallerMemberName] string callerName = "")
    {
        Application.Current.Exit += (s, e) =>
        {
            const string allowedCallingMethod = "ButtonBase_OnClick"; // todo: Set your calling method here
    
            if (callerName == allowedCallingMethod)
            {
                Process.Start(Application.ResourceAssembly.Location);
            }
         };
    
         Application.Current.Shutdown(); // Environment.Exit(0); would also suffice 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多