Перезапустите приложение само по себе

Я хочу создать свое приложение с функцией перезапуска. я нашел на 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();

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

Редактировать:

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

person Noli    schedule 07.03.2012    source источник
comment
Что происходит, какие-то исключения или просто ничего?   -  person Paulie Waulie    schedule 07.03.2012
comment
Это вообще не работает - плохое описание проблемы. Что не работает? Ошибки? Исключения? Что-то другое?   -  person Oded    schedule 07.03.2012
comment
Вы уверены, что это правильные аргументы? Похоже, он попытается удалить ваше приложение! В общем, вам нужно, чтобы какой-то другой процесс перезапустил его для вас - что они пытаются сделать здесь с помощью cmd - хотя, возможно, родительский процесс может просто сам CreateProcess или даже каким-то образом создать новый AppDomain в процессе и уничтожить старый один?   -  person Rup    schedule 07.03.2012
comment
К вашему сведению, C#.NET не существует. Язык называется C#.   -  person John Saunders    schedule 07.03.2012
comment
Согласно вашим различным комментариям ниже, вы не можете терпеть два экземпляра приложения одновременно. Можно ли использовать механизм синхронизации, такой как именованный мьютекс, чтобы гарантировать, что не более одного экземпляра пытается выполнить полезную работу? Второй экземпляр может быть запущен, но вы можете немедленно закрыть его, если уже есть продуктивный экземпляр. Для перезапуска первый экземпляр освободит мьютекс, инициирует перезапуск и выйдет.   -  person HABO    schedule 07.03.2012


Ответы (10)


Я использую код, аналогичный коду, который вы пробовали при перезапуске приложений. Я отправляю синхронизированную команду 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 не может обработать без кавычек.

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

person Bali C    schedule 08.03.2012
comment
Это отличное решение, но использование команды ping в качестве задержки делает его немного «грязным» — к сожалению, не похоже, что есть какой-либо другой способ сделать это — я попробовал (пакетную) команду «sleep», и она не работает. - person dodgy_coder; 15.05.2012
comment
Спасибо. Да, это немного хакерски, но это означает, что вы можете надежно перезапустить приложение без необходимости устанавливать что-либо еще отдельно. Я думаю, что пакетная команда sleep является дополнительной, которую вам нужно установить вручную. - person Bali C; 15.05.2012
comment
Двухсекундная пауза у меня не работает. Он просто немедленно запускает указанное приложение. В моем случае я использую приложение для обновления, которое затем дает сбой, потому что работающее приложение еще не закрылось, выпустив свои файлы. Я использую .NET 4.5.1 в Windows 10. - person Craig; 09.11.2016
comment
Спасибо, это отлично сработало для меня. Я просто предлагаю написать Info.arguments = $/C ping 127.0.0.1 -n 4 && {Environment.CommandLine}, чтобы перезапустить приложение с сохранением аргументов, которые были предоставлены при первоначальном запуске. - person Kro; 31.10.2018
comment
Вместо Application.ExecutablePath лучше использовать Process.GetCurrentProcess().MainModule.FileName В некоторых местах нельзя вызывать ExecutablePath - person Guy; 09.07.2019
comment
Для команды, которая работает как в Windows, так и в Linux (проверено на Debian), я использую ping 127.0.0.1 -w 2. Не проверено на Mac. - person Lunar; 09.05.2021

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

Application.Restart();

??

Подробнее о перезагрузке

person Shai    schedule 07.03.2012
comment
@Ноли: Почему? Это делает именно то, что вы просили: Shuts down the application and starts a new instance immediately. - person Christoph Fink; 07.03.2012
comment
Application.Restart не работает. Он редко закрывает приложение, вызывающее функцию. Это очень ненадежно. - person JeremyK; 07.03.2012
comment
Работает только в формах - person Goldorak84; 02.02.2017

Почему не только следующее?

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

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

person Christoph Fink    schedule 07.03.2012
comment
Я забыл, я не хочу, что это приложение открывается дважды одновременно. - person Noli; 07.03.2012
comment
@Noli Об этом позаботится вторая строка. - person user247702; 07.03.2012
comment
Затем попробуйте "/C choice /C Y /N /D Y /T 3 & "+Application.ExecutablePath;, так как Del удалит ваше приложение, но все же может случиться так, что приложение запустится дважды, если закрытие займет больше 3 секунд... - person Christoph Fink; 07.03.2012
comment
Это выше запустит приложение ДВАЖДЫ, поэтому в течение очень короткого времени оба будут активны, пока в строке 2 текущий процесс не будет отменен. - person Noli; 07.03.2012
comment
Почему это так важно (если вы скажете нам, что мы можем найти лучший способ)? Особенно, если вы используете Environment.Exit(-1), это может быть несколько мс, и первый будет закрыт до того, как новый процесс будет полностью запущен... - person Christoph Fink; 07.03.2012
comment
@Noli Я не вижу в этом проблемы. Если вы перезапускаете свое приложение, оно не должно ничего делать в этот момент, поэтому не имеет значения, если оно активно в течение очень короткого времени. - person user247702; 07.03.2012
comment
У меня есть опыт, когда Exit не закрывает приложение при вызове. - person JeremyK; 07.03.2012
comment
@JeremyK: Возможно, с Application.Exit, поскольку другие компоненты могут отменить это событие, но Environment.Exit завершает процесс. - person Christoph Fink; 07.03.2012

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

Чтобы запустить процесс:

Process.Start("A.exe");

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

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

foreach (Process proc in procs)
   proc.Kill();
person Mentezza    schedule 07.03.2012
comment
Да! Вот почему я использовал команду выше, app. B — ЦМД. Я хочу, чтобы это началось снова, все в порядке, что оно будет удалено. Просто скажи мне, как :D - person Noli; 07.03.2012
comment
comment
Мне это очень нравится. Я бы назвал программу Б Терминатором. Приятно то, что Terminator может ждать, пока A.exe завершится, сколько бы времени это ни требовалось. - person henon; 01.06.2016

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

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

or,

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

        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
            {
            }
        }
person JeremyK    schedule 07.03.2012
comment
Заявления об отладке субъективны. Тот, кто использует код, может обращаться с ним по своему усмотрению. - person JeremyK; 16.02.2017

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

person Avner Shahar-Kashtan    schedule 07.03.2012
comment
Application.Restart не работает. Он редко закрывает приложение, вызывающее функцию. Это очень ненадежно - person JeremyK; 07.03.2012

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

Пример командного файла Windows ("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();
person dodgy_coder    schedule 15.05.2012

Мое решение:

        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;
            }
        }
    }
person Martin.Martinsson    schedule 04.07.2016
comment
У вас все еще есть два запущенных экземпляра. - person Noli; 05.07.2016
comment
Починил это. Lock() и MethodInvoker, если вы используете его внешним потоком! - person Martin.Martinsson; 24.07.2016

Это сработало для меня:

Process.Start(Process.GetCurrentProcess().MainModule.FileName);
Application.Current.Shutdown();

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

person bwall    schedule 16.11.2020

Для .Net решение приложения выглядит так:

System.Web.HttpRuntime.UnloadAppDomain()

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

System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
configuration.AppSettings.Settings["SiteMode"].Value = model.SiteMode.ToString();
configuration.Save();
person Pal    schedule 17.08.2016