Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何重新启动WPF应用程序?_C#_.net_Wpf_.net 4.0 - Fatal编程技术网

C# 如何重新启动WPF应用程序?

C# 如何重新启动WPF应用程序?,c#,.net,wpf,.net-4.0,C#,.net,Wpf,.net 4.0,如何重新启动WPF应用程序? 在我使用的windows窗体中 System.Windows.Forms.Application.Restart() 如何在WPF中执行此操作?我发现: 它起作用了。 但是 还有更好的办法吗 System.Diagnostics.Process.Start(Application.ResourceAssembly.Location); Application.Current.Shutdown(); 我已在WPF中成功地使用了此功能: System.Windows.

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

System.Windows.Forms.Application.Restart()

如何在WPF中执行此操作?

我发现: 它起作用了。 但是 还有更好的办法吗

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

我已在WPF中成功地使用了此功能:

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

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

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

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

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

// Launch the restart batch file
Process.Start(@"C:\Dev\restart.bat");

// Close the current application
Application.Current.MainWindow.Close();

在我的程序中,我有一个互斥锁,以确保只有一个应用程序实例在计算机上运行。这导致新启动的应用程序无法启动,因为互斥锁没有及时释放。因此,我在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()中

就这样

 Application.Restart();
 Process.GetCurrentProcess().Kill();
工作对我来说很有魅力

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

按照我的顺序,另一种方法是启动应用程序的另一个实例。

在延迟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.getExecutionGassembly().Location

这:
Assembly.GetEntryAssembly().Location

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

及-

而不是:
Application.Current.Shutdown()

这:
Process.GetCurrentProcess().Kill()


它在WinForms和WPF中都能工作,如果您编写的dll是为这两种格式设计的,那么它就非常重要。

以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 
}

可能的重复项:。大家的共识是,WinForms way没有完全相同的版本,而且所有的“解决方案”都有点老套。我怀疑这是因为除了在调试期间,您通常不需要这样做。@Cody Gray现在我再次调用应用程序之星上调用的那些方法。它工作得很好。但对于其他应用程序,我必须重新启动应用程序。@Cody Gray为什么说一个人永远不需要这个?应用程序可能需要重新启动的原因有很多,当您可以为用户重新运行可执行文件时,为什么要强迫用户重新运行该文件?@epalm:仅此而已:除了在调试期间,我想不出一个应用程序需要重新启动的原因。也许你已经自动下载并安装了更新,但这可能应该通过一个单独的更新程序应用程序来完成,可能只会在启动/关闭时发生,并且应该让用户决定是否要继续在应用程序中工作(一个la Firefox和Chrome)。@Cody Gray-下面是一个例子(除非你能给我一个更好的方法)。我们正在运行一个使用WPF连接到服务器的应用程序。它会发现服务器,然后使用该发现信息编写客户端配置。该应用程序在重新启动之前无法使用此信息,因此在下载配置后,我们必须重新启动。我认为仅为此包含WinForms程序集引用有点过火。@commanderz我倾向于同意,但是我已经在使用WinForms magic,比如
System.Windows.Forms.FolderBrowserDialog()
在同一个项目中。@MatějZábský甚至在使用ClickOnce时都是必要的。这是我发现的重新启动ClickOnce应用程序的唯一方法。谢谢。@anderinea否。但只需在开始时保存它们,并将它们作为参数传递给此函数调用。这很简单。请注意,如果应用程序是用C部署的,则不想使用此方法ClickOnce。重新启动时,
ApplicationDeployment.IsNetworkDeployed
将为false。有关详细信息,请参阅。如果应用程序未使用ClickOnce进行部署,则此方法非常有效。@blachniet谢谢。请记下它。@ChristianMark,它可能没有效果。这取决于您的应用程序。过去我曾在一些应用程序上使用过它ClickOnce和普通安装程序部署,其中某些部分的行为根据是否
ApplicationDeployment而有所不同。IsNetworkDeployed
是否为true。例如,如果您是ClickOnce部署在一个组织内,则可以推断您应该有权访问组织网络资源(文件共享、电子邮件服务器等)。如果要保留命令行参数,可以首先从
Environment.GetCommandLineArgs()获取它们
然后将它们传递给进程。开始方法在睡眠状态下编写批处理文件感觉像是一个漫长的黑客行为,但可能更糟。@Philliproso同意,这是一个黑客行为,当时我需要为重新启动的应用程序提供一个全新的windows进程,我认为这里的其他方法没有提供,但这个方法提供了。这个答案是这样的(标记为答案)具有误导性。最初的问题是关于重新启动WPF应用程序,与WinForms中的操作非常相似。不幸的是,您的答案仍然使用WinForms重新启动(WPF中不可用的东西),并且还包含与所问问题无关的示例(如互斥体?).可能对WPF唯一的答案有误导性,但与其他答案结合起来对我很有用,因为我是一个新手
 Application.Restart();
 Process.GetCurrentProcess().Kill();
Application.Current.Shutdown();
System.Windows.Forms.Application.Restart();
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();
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 
}