2012-03-07 4 views
12

Я хочу, чтобы мое приложение с функцией перезапустило себя. Я нашел на CodeProjectПерезапустить приложение самостоятельно

ProcessStartInfo Info=new ProcessStartInfo(); 
Info.Arguments="/C choice /C Y /N /D Y /T 3 & Del "+ 
       Application.ExecutablePath; 
Info.WindowStyle=ProcessWindowStyle.Hidden; 
Info.CreateNoWindow=true; 
Info.FileName="cmd.exe"; 
Process.Start(Info); 
Application.Exit(); 

Это не работает на всех ... И другая проблема, как запустить его снова, как это? Возможно, есть и аргументы для запуска приложений.

Edit:

http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=31454&av=58703 
+0

Что происходит, любые исключения или просто ничего? –

+3

«Это совсем не работает» - плохое описание проблемы. Что не работает? Ошибки? Исключения? Что-то другое? – Oded

+0

Вы уверены, что это правильные аргументы? Похоже, что он попытается удалить ваше приложение! В общем, вам понадобится перезапустить его для другого - для чего он пытается работать с cmd - хотя возможно, что родительский процесс может просто создать CreateProcess сам или даже каким-то образом создать новый AppDomain в процессе и уничтожить старый один? – Rup

ответ

36

Я использую аналогичный код для кода, который вы пытались перезапустить приложения. Я посылаю приуроченный CMD команду, чтобы перезапустить приложение для меня, как это:

ProcessStartInfo Info = new ProcessStartInfo(); 
Info.Arguments = "/C ping 127.0.0.1 -n 2 && \"" + Application.ExecutablePath + "\""; 
Info.WindowStyle = ProcessWindowStyle.Hidden; 
Info.CreateNoWindow = true; 
Info.FileName = "cmd.exe"; 
Process.Start(Info); 
Application.Exit(); 

Команда отправляется ОС, пинг останавливает сценарий в течение 2-3 секунд, за это время приложение покинуло от Application.Exit() , затем следующая команда после пинга снова запускает ее.

Примечание: \" ставит кавычки вокруг пути, если он имеет пробелы, которые cmd не может обрабатывать без кавычек.

Надеюсь, это поможет!

+0

Это решение является удивительным, но использование команды ping в качестве задержки заставляет его чувствовать себя немного «грязным» - к сожалению, похоже, что нет другого способа сделать это - я попробовал (пакетную) команду «sleep» и он не работает. –

+0

Спасибо. Да, это немного взломанно, но это означает, что вы можете надежно перезапустить приложение, не устанавливая ничего другого отдельно. Я думаю, что командная команда 'sleep' является дополнительной, которую вы должны установить вручную. –

+1

Две секундные паузы не работают для меня. Он просто запускает указанное приложение немедленно. В моем случае я использую приложение updater, которое затем терпит неудачу, потому что запущенное приложение еще не закрывает выпуск его файлов. Я использую .NET 4.5.1 в Windows 10. – kraeg

9

Почему бы не просто следующий?

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

Если вы хотите быть уверены, что приложение не работает в два раза либо использовать Environment.Exit(-1), который убивает процесс мгновенно (на самом деле не хороший способ) или что-то вроде запуска второго приложения, который проверяет процесс основных приложение и запускает его снова, как только процесс исчезнет.

+0

Я забыл, я не хочу, чтобы это приложение открывалось дважды в одно и то же время. – Noli

+1

@Noli Вторая линия заботится об этом. – Stijn

+0

Затем попробуйте ''/C choice/CY/N/DY/T 3 & "+ Application.ExecutablePath;' поскольку «Del» удалит ваше приложение, но все равно может случиться, что приложение запускается дважды, если закрытие занимает дольше, чем 3s ... – ChrFin

24

Почему бы не использовать

Application.Restart(); 

??

Подробнее о Restart

+0

Не знал этого метода, и я думаю, что это лучший способ пойти ... – ChrFin

+0

Пожалуйста, мне нужен другой способ ... – Noli

+0

@Noli: Почему? Это делает именно то, что вы просили: «Закрывает приложение и немедленно запускает новый экземпляр». – ChrFin

3

Winforms имеет Application.Restart() метод, который делает именно это. Если вы используете WPF, вы можете просто добавить ссылку на System.Windows.Forms и позвонить ему.

+0

Application.Restart не работает. Он редко отключает приложение, вызывающее функцию. Это очень ненадежно. – JeremyK

+0

Он работал отлично для меня до сих пор в приложении WPF. –

+0

не работает для приложения WPF – Sandepku

6

У вас есть начальное приложение A, которое необходимо перезапустить. Итак, когда вы хотите, чтобы убить, начинается небольшое приложение B, B убить А, то начать, и убить В.

Чтобы начать процесс:

Process.Start("A.exe"); 

Чтобы убить процесс , что-то вроде этого

Process[] procs = Process.GetProcessesByName("B"); 

foreach (Process proc in procs) 
    proc.Kill(); 
+0

Да! Вот почему я использовал команду выше, приложение. B - «CMD». Я хочу, чтобы это началось снова, все в порядке, что он будет удален. Просто скажите мне, как: D – Noli

+0

Лучше использовать [Process.ID] (https://msdn.microsoft.com/en-us/library/system.diagnostics.process.id%28v=vs.110%29.aspx) и [Process.GetProcessById] (https://msdn.microsoft.com/en-us/library/76fkb36k%28v=vs.110%29.aspx) – Brettetete

+0

Мне это очень нравится. Я бы назвал программу B «Терминатор». Самое приятное, что Terminator может дождаться, когда A.exe завершит работу, но в течение долгого времени ему нужно – henon

2

Многие люди предлагают использовать Application.Restart. В действительности эта функция редко работает так, как ожидалось. Я никогда не закрывал приложение, из которого я его вызываю. Мне всегда приходилось закрывать приложение с помощью других методов, таких как закрытие основной формы.

У вас есть два способа справиться с этим. Вы должны либо внешнюю программу, которая закрывает процесс вызова и начинает новую,

или

у вас есть начало вашего нового программного обеспечения убивать других экземпляров одного и того же приложения, если аргумент передается как рестарта.

 private void Application_Startup(object sender, StartupEventArgs e) 
     { 
      try 
      { 
       if (e.Args.Length > 0) 
       { 
        foreach (string arg in e.Args) 
        { 
         if (arg == "-restart") 
         { 
          // WaitForConnection.exe 
          foreach (Process p in Process.GetProcesses()) 
          { 
           // In case we get Access Denied 
           try 
           { 
            if (p.MainModule.FileName.ToLower().EndsWith("yourapp.exe")) 
            { 
             p.Kill(); 
             p.WaitForExit(); 
             break; 
            } 
           } 
           catch 
           { } 
          } 
         } 
        } 
       } 
      } 
      catch 
      { 
      } 
     } 
+0

Все, что игнорировало исключения с пустыми блоками 'catch' ... Ewww .... – jeuxjeux20

+0

Отладочные заявления субъективны. Тот, кто использует код, может справиться с этим, как им нравится. – JeremyK

1

Другим способом сделать это, который чувствует себя немного чище, чем эти решения, является запуск командного файла, который включает определенную задержку для ожидания завершения текущего приложения. Это дает дополнительное преимущество, предотвращая одновременное открытие двух экземпляров приложения.

Пример окна пакетного файла ("restart.bat"):

sleep 5 
start "" "C:\Dev\MyApplication.exe" 

В приложении, добавьте этот код:

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

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

// Close the current application (for WinForms case) 
Application.Exit(); 
1

Мое решение:

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

     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 
      { 
       List<Form> openForms = Application.OpenForms.OfType<Form>().ToList(); 

       for (int i = openForms.Count - 1; i >= 0; i--) 
       { 
        Form f = openForms[i]; 

        if (f.InvokeRequired) 
        { 
         f.Invoke(new MethodInvoker(() => 
         { 
          f.FormClosing += (sender, args) => cancelExit = args.Cancel; 
          f.Close(); 
         })); 
        } 
        else 
        { 
         f.FormClosing += (sender, args) => cancelExit = args.Cancel; 
         f.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

У вас все еще есть две запущенности. – Noli

+0

Исправлено. Lock() и MethodInvoker, если вы используете его по внешнему потоку! –

0

Для. Решение Net Application выглядит так:

System.Web.HttpRuntime.UnloadAppDomain() 

Я использовал это для перезапуска моего веб-приложения после изменения AppSettings в файле myconfig.

System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~"); 
configuration.AppSettings.Settings["SiteMode"].Value = model.SiteMode.ToString(); 
configuration.Save(); 
Смежные вопросы