it-swarm-eu.dev

Proč není Application.Restart () spolehlivý?

Použití metody Application.Restart() v C # by mělo restartovat aktuální aplikaci: ale zdá se, že to nefunguje vždy.

Existuje nějaký důvod pro tuto záležitost, může mi někdo říct, proč to pořád nefunguje?

42
MADMap

Pro to by mohlo být mnoho důvodů. Není to tak, že metoda nefunguje; poněkud, mnohokrát programátoři zapomínají, že oni dali něco do jejich kódu, který by zastavil aplikaci z automatického vypnutí, nebo spuštění. Dva příklady:

  • Závěrečná událost ve formuláři může zastavit vypnutí aplikace
  • Pokud provádíte kontrolu již běžícího procesu, starý se nemusí dostatečně rychle zavírat, aby umožnil spuštění nového.

Zkontrolujte svůj kód pro gotchas takhle. Pokud toto chování vidíte v rámci prázdné aplikace, je to pravděpodobnější problém se skutečnou funkcí než kód.

Zkontrolujte zdrojový kód společnosti Microsoft restart aplikace .

27
TheSmurf

V mém případě (NO single-instance), kde

Application.Restart();

nefungovalo,

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

udělal práci!

18
cprcrack

Jediný čas, kdy jsem narazil na tento druh problému, je, když jsem měl v mé hlavní formě vlastní obslužný program FormClosing event, který provedl logiku a zrušil událost.

UPRAVIT:

Nyní jsem narazil na jinou instanci a na základě vašich komentářů to může odrážet to, co jste zažívali. 

Když používáte aplikaci s jednou instancí, používající Mutex, zavolal jsem na Application.Restart() z poměrně vloženého umístění, které mělo spoustu vyčištění. Zdá se tedy, že restart byl spuštění nové instance před dokončením předchozí instance, takže Mutex udržel novou instanci od spuštění.

7
Timothy Carter

V mém programu mám mutex, abych zajistil pouze jednu instanci aplikace běžící na počítači. To způsobilo, že nově spuštěná aplikace nezačala, protože mutex nebyl uvolněn včas. V důsledku toho vložím hodnotu do Properties.Settings, která označuje, že se aplikace restartuje. Před voláním Application.Restart() je hodnota Properties.Settings nastavena na true . V Program.Main() jsem také přidal kontrolu pro tuto specifickou hodnotu property.settings, takže když true je resetováno na false a existuje Thread.Sleep(3000);

Ve vašem programu můžete mít logiku:

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

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

A je to.

5
cmptrs4now

Vyzkoušejte uzamčení před dumpingem. Zde je návod, jak inicializovat úplný výpis aplikací. Mohlo by to pro vás fungovat, možná ne.

Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock();
2
Oli

Pokud byla aplikace poprvé spuštěna ze síťového umístění a je nepodepsaná (nejprve se zobrazí dialogové okno s upozorněním), nebude restartován a bude ukončen.

1
Matt Hanson
Application.Restart();
Application.ExitThread();                                                     

to pro mě fungovalo díky.

1
shima lagzian

Vyzkoušejte tento kód:

bool appNotRestarted = true;

Tento kód musí být také ve funkci:

if (appNotRestarted == true)
{
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}
1
ferhatayhan

Vím, že je to staré vlákno, ale našel jsem řešení. Doufejme, že to pomůže někomu jinému v nouzi. 

Potřeboval jsem řešení, které by spustilo sekvenci aktualizace během spouštění aplikace ClickOnce z kódu. Applicatoin.Restart to neučinil. Chtěl jsem způsob, jak zkontrolovat aktualizaci a pak vyvolat vestavěného správce aktualizací, abych nemusel psát vlastní.

    '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

Jediný problém, který vidím s tímto řešením je, že uživatel mohl odstranit zástupce z nabídky Start. Pokud se jedná o problém, můžete napsat nějaký kód zkopírovat odkaz na nabídku Start do některé složky podle vašeho výběru, nejlépe ve složce aplikace ClickOnce. To je důležité, protože ikona nabídky Start pro vaši aplikaci není .lnk nebo .exe, je to vlastně odkaz .appref-ms. Viz ClickOnce .appref-ms více než odkaz na soubor .application? Tento odkaz to podrobněji vysvětluje.

Tento kód bude fungovat s aplikacemi ClickOnce SingleInstance.

0
Nathan
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;
            }
        }
    }
0

Mám tento velmi stejný problém s .Net 4.7 framework. Přijatá odpověď byla pro můj úspěch klíčová.

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

pouze pak Application.Restart () pracoval!

0
Nandostyle