1

Is it possible to do something like the following:

bool wasRestarted = ???;
main() {
    if(wasRestarted) {
        MessageBox.Show("Welcome Back John");
    }
    Application.Restart();
}

This is specifically to the Application.Restart and NOT soft closing and reopening.

Only way I can think of right now is by creating a Setting Value:

  • Type: int
  • Default: 0

Set it to 1 before restarting, then check for 1.

There has to be a better way then this?

Selected Answer worked perfect! As usual, thanks to the community for bringing a new feature to my brain :P

I used this to do a workaround for releasing a Mutex on Application.Restart on another thread. Since Mutex's are Thread Locked, I couldn't release a mutex on a login funtion before restarting, causing the Restart to return a locked mutex and couldnt continue. With this, I could know if it restarted, then do a simple while with a delay until the first "Application" actually closed and prematurely Program's Main() closed off resulting in the Mutex being cleared. The while() will then continue, and now my app works like normal!

Obviously for my needs, this wasn't the most ideal outcome, but it does work, and thats all I can ask for.

Ma Dude
  • 477
  • 1
  • 5
  • 17

4 Answers4

3

Do you have access to the file system? If so, write a config file that saves your exit state. If exiting normally save as (say) 0, when restarting save as a 1 and then read this file when starting up. When starting for the first time this file may not be present (unless it's part of your installer) so assume a 0 if not present.

If you are on Windows you could also use a registry setting too. It's not hard.

DaveEP
  • 1,426
  • 4
  • 13
  • 27
  • Thats essentially the same as the Settings thing I though about earlier. – Ma Dude Jun 08 '18 at 07:26
  • The problem with this solution (file or registry) is that multiple instances of the same application can interfere with each other. – huysentruitw Jun 08 '18 at 07:51
  • 1
    @Wouter that is correct and just one more issue the user has to deal with if that's the case. It's going to be interesting seeing someone running multiple instances of a GUI program where it's worth welcoming someone back on a restart :) – DaveEP Jun 08 '18 at 07:53
3

You can use a temporary environment variable for that:

// Set environment variable before calling Restart
Environment.SetEnvironmentVariable("MYAPP_RESTART", "1");
Application.Restart();

// Detect restart:
var wasRestarted = Environment.GetEnvironmentVariable("MYAPP_RESTART");

if (wasRestarted == "1")
{
    // Your app was restarted
    Environment.SetEnvironmentVariable("MYAPP_RESTART", "0");
}
huysentruitw
  • 27,376
  • 9
  • 90
  • 133
  • Oh wow, thats new! Is there any incompatability issues with old OS's? I need support for 7, 8, 8.1, 10, Server 2008 R2 and above. (Vista is already unsupported). – Ma Dude Jun 08 '18 at 07:36
  • I don't think so, environment variables exist since DOS :) – huysentruitw Jun 08 '18 at 07:37
  • 1
    Perfect! Worked like a charm. – Ma Dude Jun 08 '18 at 07:39
  • whats the difference in using this or a config file or the settings ? Its just another place to write your value in for the rest its all the same or am I missing something ? – GuidoG Jun 08 '18 at 07:42
  • @GuidoG With settings, there could be File Access issues especially if your multi-instancing or doing a lot of operations on it already. And you gotta do extra stuff with the settings way like having to reset it back to 0 after the restart. – Ma Dude Jun 08 '18 at 07:43
  • Just for clearity, dont you have to clear the environment variable also after the restart ? So its again the same thing ? – GuidoG Jun 08 '18 at 07:45
  • @GuidoG a config file can be read / written by multiple application instances. By using this temporary variable trick, you're sure you're passing the state to the correct instance that is restarting. – huysentruitw Jun 08 '18 at 07:45
  • 1
    @WouterHuysentruit Yes thats a better reason to use this approach – GuidoG Jun 08 '18 at 07:46
  • @BugFinder also, the next time the user starts the application, it won't have this variable in the environment, because the application is started from a fresh environment, it's a pretty fail-safe trick IMO :) – huysentruitw Jun 08 '18 at 07:50
0

You could pass a (command line alike) argument to main when you restart it. Default it to 0 so as default you do not show the welcome back box.

As for how to change arguments before restarting, please check Modify command line arguments before Application.Restart()

Attersson
  • 4,755
  • 1
  • 15
  • 29
  • is something like this supported by .Application.Restart? – Ma Dude Jun 08 '18 at 07:19
  • Restart will restart the application with exact the same command line arguments as the first start. See https://msdn.microsoft.com/en-us/library/system.windows.forms.application.restart(v=vs.110).aspx – huysentruitw Jun 08 '18 at 07:21
  • See [the source code of `Application.Restart`](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Application.cs,1392) and roll your own version that takes additional parameters. – Uwe Keim Jun 08 '18 at 07:22
  • @WouterHuysentruit Never knew that, thanks, unfortuanately that wont help my case then :( Unless I can edit the arguments after load and it would see the changes? Or would it just ignore them – Ma Dude Jun 08 '18 at 07:22
  • @UweKeim oh wow, handy reference page, im gonna be looking into that for TcpClient later! :D – Ma Dude Jun 08 '18 at 07:23
  • Actually, upon further research, you can. https://stackoverflow.com/questions/37769194/modify-command-line-arguments-before-application-restart – Attersson Jun 08 '18 at 07:26
0

If it's about restarting the application, you don't need to store a setting.

If it's not about restarting and it's about the next time which user opens the application, then you definitely need to store a setting.

Here in this answer I'll share the solution to say "Welcome back!" to user, after restarting the application. To do so. Here in the following example, using the source code of Application.Restart I've implemented a Restart method for Program class and passed a command-line argument which shows application has been restarted:

To use, it's enough to call Program.Restart().

static class Program
{
    private static string restartArg =  "-restart";
    public static void Restart()
    {
        var startInfo = System.Diagnostics.Process.GetCurrentProcess().StartInfo;
        startInfo.FileName = Application.ExecutablePath;
        var exit = typeof(Application).GetMethod("ExitInternal",
                            System.Reflection.BindingFlags.NonPublic |
                            System.Reflection.BindingFlags.Static);
        exit.Invoke(null, null);
        startInfo.Arguments = restartArg;
        System.Diagnostics.Process.Start(startInfo);
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var restarted = Environment.CommandLine.Contains(restartArg);
        if (restarted)
            MessageBox.Show("Welcome back!");
        Application.Run(new Form1());
    }
}

If you like to use the original commandline arguments and manipulate it rather than eliminating it, then take a look at this post:

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398