2012-03-07 3 views
12

자체 응용 프로그램을 다시 시작하는 기능으로 응용 프로그램을 빌드하려고합니다. 나는응용 프로그램을 단독으로 다시 시작하십시오.

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

이 이런 식으로 다시 모두 ... 그리고 다른 문제는, 어떻게 시작하는 것입니다 작동하지 않습니다 CodeProject의에 발견? 아마도 응용 프로그램을 시작하기위한 인수가있을 수도 있습니다.

편집 :

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

예외는 무엇입니까? –

+3

"전혀 작동하지 않습니다"는 문제에 대한 설명이 잘못되었습니다. 작동하지 않는 것은 무엇입니까? 오류? 예외? 다른 것? – Oded

+0

그게 올바른 주장입니까? 귀하의 신청서를 삭제하려고 시도하는 것 같습니다. 일반적으로 부모 프로세스가 CreateProcess 자체 만 만들거나 프로세스 내에서 새로운 AppDomain을 만들고 이전 프로세스를 파괴 할 수는 있지만 cmd를 사용하여 다른 프로세스가 다시 시작해야합니다. 하나? – 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(); 

명령은 OS로 전송이 ping이 응용 프로그램이 Application.Exit()에서 종료시킨 시간 2~3초에 대한 스크립트를 일시 중지 , ping 후에 다음 명령이 다시 시작됩니다.

참고 : \"은 경로 주위에 따옴표를 넣습니다. 공백이 있으면 cmd는 따옴표없이 처리 할 수 ​​없습니다.

희망이 도움이됩니다.

+0

이 솔루션은 훌륭하지만 ping 명령을 지연으로 사용하면 조금 더러운 느낌이납니다 - 불행히도 다른 방법이없는 것처럼 보입니다 - 나는 (배치) 'sleep'명령을 시도하고 작동하지 않습니다. –

+0

감사합니다. 그래, 조금 해키지만, 그것은 당신이 안정적으로 아무것도 별도로 설치하지 않고도 응용 프로그램을 다시 시작할 수 있다는 것을 의미합니다. 배치'sleep '명령은 수동으로 설치해야하는 추가 기능이라고 생각합니다. –

+1

두 번째 일시 중지가 작동하지 않습니다. 지정된 응용 프로그램을 즉시 시작합니다. 필자의 경우, 실행중인 응용 프로그램이 아직 파일을 종료하지 못하기 때문에 실패한 업데이터 응용 프로그램을 사용하고 있습니다. Windows 10에서 .NET 4.5.1을 사용하고 있습니다. – 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"으로 삭제하면 응용 프로그램이 삭제되지만 닫을 수 있으면 응용 프로그램이 두 번 실행될 수도 있습니다 more than 3s ... – ChrFin

24

Application.Restart(); 

사용 ?? Restart

+0

그 방법을 몰랐고, 이것이 최선의 방법이라고 생각합니다 ... – ChrFin

+0

제발, 다른 방법이 필요합니다 ... – Noli

+0

@ 놀리 : 왜? 이것은 정확히 당신이 요구 한대로합니다 :'애플리케이션을 종료하고 즉시 새로운 인스턴스를 시작합니다 .' – ChrFin

3

윈폼에

더 그냥을 수행하는 Application.Restart() 방법을 가지고 있습니다. WPF를 사용하는 경우 System.Windows.Forms에 대한 참조를 추가하고 호출하면됩니다.

+0

응용 프로그램에서만 작동합니다. 다시 시작되지 않습니다. 함수를 호출하는 응용 프로그램을 종료하는 경우는 거의 없습니다. 그것은 매우 신뢰할 수 없습니다 – JeremyK

+0

WPF 응용 프로그램에서 지금까지 저에게 잘 작동했습니다. –

+0

WPF 앱에서 작동하지 않습니다 – Sandepku

6

초기 응용 프로그램 A가 있고 다시 시작해야합니다.

Process.Start("A.exe"); 

이 프로세스를 종료하려면 : 당신이 죽이고 싶어 때, 약간의 애플리케이션 B가 시작 는 B 킬 A, 후 B는 프로세스를 시작하려면를 시작하고

B.

을 죽일 , 이와 비슷한 것입니다

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

합니다. 닷넷 어플리케이션 솔루션은 다음과 같습니다 :

System.Web.HttpRuntime.UnloadAppDomain() 

myconfig 파일에서 AppSettings를 변경 한 후 웹 응용 프로그램을 다시 시작하는 데이 방법을 사용했습니다.

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