web-dev-qa-db-ja.com

アプリケーションを単独で再起動する

自分自身を再起動する機能を備えたアプリケーションを構築したい。 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
17
Noli

アプリを再起動するときに試したコードと同様のコードを使用します。私はこのようにアプリを再起動するために時限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(); 
_

コマンドはOSに送信され、pingは2〜3秒間スクリプトを一時停止します。その間にアプリケーションはApplication.Exit()から終了し、pingの次のコマンドが再び開始します。

注:_\"_は、スペースが含まれている場合にパスを引用符で囲み、cmdは引用符なしでは処理できません。

お役に立てれば!

40
Bali C

なぜ使わない

Application.Restart();

再起動 の詳細

28
Shai

なぜ次だけではないのですか?

_Process.Start(Application.ExecutablePath); 
Application.Exit();
_

アプリが2回実行されないようにしたい場合は、Environment.Exit(-1)を使用してプロセスを即座に強制終了します(実際にはナイスな方法ではありません)。プロセスが終了するとすぐに再起動します。

9
ChrFin

最初のアプリケーションAがあり、再起動したい場合。したがって、Aを殺すには、小さなアプリケーションBが開始され、BがAを殺し、次にBがAを開始し、Bを殺します。

プロセスを開始するには:

Process.Start("A.exe");

プロセスを強制終了するには、このようなものです

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

foreach (Process proc in procs)
   proc.Kill();
6
Mentezza

多くの人がApplication.Restartの使用を提案しています。実際には、この機能が期待どおりに機能することはほとんどありません。呼び出し元のアプリケーションをシャットダウンしたことがありません。メインフォームを閉じるなど、他の方法でアプリケーションを閉じる必要がありました。

これを処理するには2つの方法があります。呼び出しプロセスを閉じて新しいプロセスを開始する外部プログラムがあるか、

または、

引数が再起動として渡された場合、新しいソフトウェアを起動して同じアプリケーションの他のインスタンスを強制終了します。

        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
            {
            }
        }
3
JeremyK

Winformsには Application.Restart() メソッドがあり、これを実行します。 WPFを使用している場合は、System.Windows.Formsへの参照を追加して呼び出すだけです。

私の解決策:

        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;
            }
        }
    }
1

これらの解決策よりもすっきりと感じる別の方法は、現在のアプリケーションが終了するのを待つ特定の遅延を含むバッチファイルを実行することです。これには、2つのアプリケーションインスタンスが同時に開かれるのを防ぐという利点もあります。

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();
1
dodgy_coder

.Netアプリケーションソリューションの場合は次のようになります。

System.Web.HttpRuntime.UnloadAppDomain()

MyconfigファイルのAppSettingsを変更した後、これを使用してWebアプリケーションを再起動しました。

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