代码之家  ›  专栏  ›  技术社区  ›  MADMap

为什么application.restart()不可靠?

  •  42
  • MADMap  · 技术社区  · 16 年前

    使用该方法 Application.Restart() 在C中,应该重新启动当前的应用程序:但这似乎并不总是有效的。

    有人能告诉我,为什么这个问题一直不起作用吗?

    11 回复  |  直到 16 年前
        1
  •  27
  •   Tomas Kubes    7 年前

    这可能有很多原因。不是方法不起作用;而是,很多时候程序员忘记了他们的代码中有一些东西会阻止应用程序自动关闭或启动。两个例子:

    • 表单上的关闭事件可以停止应用程序的关闭
    • 如果您正在检查一个已经运行的进程,则旧进程的关闭速度可能不够快,无法允许新进程启动。

    检查你的代码是否有这样的问题。如果您在空白应用程序中看到这种行为,那么实际函数的问题可能比代码的问题更大。

    检查Microsoft的源代码 application restart .

        2
  •  18
  •   cprcrack    10 年前

    在我的案例中(没有单一实例),其中

    Application.Restart();
    

    不起作用,

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

    做了那份工作!

        3
  •  7
  •   Nate B.    10 年前

    我唯一一次遇到这种问题是在我的主要形式我有一个习惯 FormClosing 事件处理程序,执行逻辑并取消事件。

    编辑:

    我现在遇到了另一个实例,根据您的评论,它可能反映了您正在经历的事情。

    当使用互斥体运行单个实例应用程序时,我正在调用 Application.Restart() 从一个相当嵌入的位置,有很多清理工作要做。因此,重新启动似乎是在上一个实例完成之前启动了一个新实例,因此互斥体使新实例无法启动。

        4
  •  5
  •   Ganesh Kamath - 'Code Frenzy'    8 年前

    在我的程序中,我有一个互斥体来确保只有一个应用程序实例在计算机上运行。这导致新启动的应用程序无法启动,因为互斥体没有及时释放。结果我把一个值 Properties.Settings 这表示应用程序正在重新启动。打电话之前 Application.Restart() 这个 属性。设置 值设置为 . 在 Program.Main() 我还加了一张支票 property.settings 价值观,所以当 它被重置为 还有一个 Thread.Sleep(3000);

    在您的程序中,您可能具有以下逻辑:

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

    程序主程序()

    [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();
       }
    }
    

    就是这样。

        5
  •  2
  •   Oli    16 年前

    在倾倒之前尝试锁定。以下是我如何启动一个完整的应用程序转储。可能会为你工作,也可能不会。

    Context.Application.Lock();
    Context.Session.Abandon();
    Context.Application.RemoveAll();
    Context.Application.Restart();
    Context.Application.UnLock();
    
        6
  •  1
  •   Matt Hanson    14 年前

    如果应用程序是从网络位置首次启动的,并且没有签名(首先会收到警告对话框),则它不会重新启动,只会退出。

        7
  •  1
  •   Zero Piraeus    12 年前

    试试这个代码:

    bool appNotRestarted = true;
    

    此代码也必须在函数中:

    if (appNotRestarted == true)
    {
        appNotRestarted = false;
        Application.Restart();
        Application.ExitThread();
    }
    
        8
  •  1
  •   Gwenc37 Anand Shukla    11 年前
    Application.Restart();
    Application.ExitThread();                                                     
    

    这对我有用,谢谢。

        9
  •  0
  •   Community CDub    8 年前

    我知道这是一条老路,但我找到了一个解决办法。希望这能帮助其他需要帮助的人。

    我需要一个解决方案,在ClickOnce应用程序从代码启动期间触发更新序列。 Applicatoin.Restart 没有这样做。我希望有一种方法能够检查更新,然后调用内置的更新管理器,这样我就不必编写自定义的更新。

        'VB Code Sample
        Dim strStart As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) & "\Programs\Folder\YourApplication.appref-ms"
        Application.Exit()
        Try
            Process.Start(strStart)
        Catch ex As Exception
            'Do something with the exception
        End Try
    

    我在这个解决方法中看到的唯一问题是,用户可以从“开始”菜单中删除快捷方式。如果这是一个问题,您可以编写一些代码来将“开始”菜单链接复制到您选择的某个文件夹中,最好是在ClickOnce应用程序文件夹中。这很重要,因为应用程序的“开始”菜单图标不是.lnk或.exe,而是.apprf-ms链接。见 ClickOnce .appref-ms more than a link to .application file? 此链接更详细地解释了这一点。

    此代码将用于ClickOnce单实例应用程序。

        10
  •  0
  •   Martin.Martinsson    8 年前
    public static void ApplicationRestart(params string[] commandLine)
        {
            lock (SynchObj)
            {
                if (Assembly.GetEntryAssembly() == null)
                {
                    throw new NotSupportedException("RestartNotSupported");
                }
    
                if (_exiting)
                    return;
    
                _exiting = true;
    
                if (Environment.OSVersion.Version.Major < 6) return;
    
                bool cancelExit = true;
    
                try
                {
                    foreach (Form f in Application.OpenForms.OfType<Form>().ToList())
                    {
                        f.InvokeIfRequired(frm =>
                        {
                            frm.FormClosing += (sender, args) => cancelExit = args.Cancel;
                            frm.Close();
                        });
    
                        if (cancelExit) break;
                    }
    
                    if (cancelExit) return;
    
                    Process.Start(new ProcessStartInfo
                    {
                        UseShellExecute = true,
                        WorkingDirectory = Environment.CurrentDirectory,
                        FileName = Application.ExecutablePath,
                        Arguments = commandLine.Length > 0 ? string.Join(" ", commandLine) : string.Empty
                    });
    
                    Application.Exit();
                }
                finally
                {
                    _exiting = false;
                }
            }
        }
    
        11
  •  0
  •   Nandostyle    7 年前

    我在.NET 4.7框架中遇到了同样的问题。公认的答案是我成功的关键。 我确实在FormClosing事件中有代码,这需要一些时间并停止重新启动过程。 我做的是让一个哨兵这样:

    If JustCloseIT = False Then
       'all closing code, like logging the session log-out to a database and all those goodies we all do.
     End If
    

    只有这样,应用程序.restart()才能工作!