48

Using the method Application.Restart() in C# should restart the current application: but it seems that this is not always working.

Is there a reason for this Issue, can somebody tell me, why it doesn't work all the time?

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
MADMap
  • 3,132
  • 3
  • 25
  • 31

12 Answers12

30

There could be a lot of reasons for this. It's not that the method doesn't work; rather, many times programmers forget that they've put something in their code that would stop the application from automatically shutting down, or starting up. Two examples:

  • The Closing event on a form can stop an app's shutdown
  • If you're doing checking for an already-running process, the old one may not be closing fast enough to allow the new one to start up.

Check your code for gotchas like that. If you're seeing this behaviour within a blank application, then that's more likely to be a problem with the actual function than your code.

Check Microsoft's sourcecode of application restart.

Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
TheSmurf
  • 15,337
  • 3
  • 40
  • 48
  • I AM using an SingleInstance-Application, but I didn't think that this can cause the problem. I rather thought .NET is smart enough to let the Process close till the next instance will start. – MADMap Sep 18 '08 at 18:47
  • 3
    @MADMap: Your single-instance check is the problem. Your old app can't die and then start the new one, because after it's dead it can't do anything. – Ben Voigt Jul 15 '13 at 23:33
  • You need to change single instance to wait for obtaining mutex for a while. – Tomas Kubes Jan 04 '18 at 15:56
20

In my case (NO single-instance), where

Application.Restart();

didn't work,

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

did the job!

cprcrack
  • 17,118
  • 7
  • 88
  • 91
7

The only time I've run into this kind of issue is when in my main form I had a custom FormClosing event handler, that performed logic and canceled the event.

EDIT:

I have now run into another instance and based on your comments it possibly mirrors what you were experiencing.

When running a single instance application, using a Mutex, I was calling Application.Restart() from a fairly embedded location, that had a lot of cleanup to do. So it seems the restart was launching a new instance before the previous instance was complete, so the Mutex was keeping the new instance from starting.

Community
  • 1
  • 1
Timothy Carter
  • 15,459
  • 7
  • 44
  • 62
6

In my program I have a mutex to ensure only one instance of the application running on a computer. This was causing the newly started application to not start because the mutex had not been release in a timely fashion. As a result I put a value into Properties.Settings that indicates that the application is restarting. Before calling Application.Restart() the Properties.Settings value is set to true. In Program.Main() I also added a check for that specific property.settings value so that when true it is reset to false and there is a Thread.Sleep(3000);

In your program you may have the logic:

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

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

That's it.

cmptrs4now
  • 69
  • 1
  • 1
  • I used your `IsRestarting` idea in my VB translation, [here](http://stackoverflow.com/questions/19367452/clickonce-application-doesnt-restart-after-upgrade-is-complete/22604449#22604449). It's a good idea, but the code block itself doesn't work well with VB's Application Framework events. It took some doing, but I finally got it working. – InteXX Mar 24 '14 at 08:59
  • 4
    This is horrible. First you're sleeping, which will never wait exactly the right amount of time. It may fail if the computer is busy and shutdown takes longer than expected. And otherwise it will waste time. Furthermore, you're using shared *persistent* state. The right solution is simply to free the `runOnce` mutex before calling `Application.Restart()`. – Ben Voigt Nov 26 '14 at 18:32
2

Try locking before dumping. Here's how I initiate a full app-dump. Might work for you, might not.

Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock();
Oli
  • 235,628
  • 64
  • 220
  • 299
  • 1
    I guess it didn't work for them. Nice of them to have left a comment if that was the case. – Oli Oct 06 '10 at 08:26
1

If the application was first launched from a network location and is unsigned (you get the warning dialog first), it won't restart and will only exit.

Matt Hanson
  • 3,458
  • 7
  • 40
  • 61
1

Extension methods:

public delegate void MethodDelegate<in TControl>(TControl value);

public static void InvokeIfRequired<TControl>(this TControl control, MethodDelegate<TControl> action)
    where TControl : Control
{
    if (control.InvokeRequired)
    {
        control.Invoke(action, control);
    }
    else
    {
        action(control);
    }
}  

Class privates:

private static bool _exiting;
private static readonly object SynchObj = new object();

Working horse:

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;
        }
    }
}
Martin.Martinsson
  • 1,894
  • 21
  • 25
1

I Tried with below code and it is working fine

static class Program
{
    static Mutex _mutex = new Mutex(false, "MYAPP");

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        if (!_mutex.WaitOne(1000, false))
        {
            MessageBox.Show("Another instance is already running!!!", "Already Running", MessageBoxButtons.OK,
                MessageBoxIcon.Error);
            return;
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new PrimaryForm());

        _mutex.ReleaseMutex();
    }
}

//the place where i am calling application restart used this code

Application.Restart();
Application.ExitThread();

Reference Link
https://www.codeproject.com/articles/25674/preventing-multiple-application-instances-when-usi

0
Application.Restart();
Application.ExitThread();                                                     

this worked for me thanks.

Gwenc37
  • 2,064
  • 7
  • 18
  • 22
0

I have this very same issue with .Net 4.7 framework. The accepted answer was key for my success. I did had code in the FormClosing event that was taking some time and stopping the restart process. What I did was to put a sentinel like this:

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

only then the Application.Restart() worked!

Nandostyle
  • 344
  • 2
  • 12
0

Try this code:

bool appNotRestarted = true;

This code must also be in the function:

if (appNotRestarted == true)
{
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
-1

I know this is an old thread, but I found a workaround. Hopefully this will help someone else in need.

I needed a solution that would trigger the update sequence during a ClickOnce Application startup from code. Applicatoin.Restart did not do this. I wanted a way of being able to check for an update and then invoking the built in update manager so that I didn't have to write a custom one.

    '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

The only issue that I see with this workaround is that a user could delete the shortcut from the start menu. If that is a concern you could write some code to copy the start menu link to the some folder of your choosing, preferably in the ClickOnce application folder. This is important because the start menu icon for your application is not a .lnk or .exe, it is actually a .appref-ms link. See ClickOnce .appref-ms more than a link to .application file? This link explains this in more detail.

This code will work with ClickOnce SingleInstance Applications.

Community
  • 1
  • 1
Nathan
  • 789
  • 11
  • 20