2013-10-05 51 views
2

我正在使用一個開發不良的應用程序,由於內存泄漏或其他隨機錯誤,不重複如果重新啓動,不斷重新啓動。我無法訪問代碼,無法修復它。我已經開發了一個C#應用程序來管理重新啓動,並保持程序運行,但它如何停止,但我如何識別一個掛起(或當它崩潰,但Windows錯誤消息,讓它「運行」)。Watcher應用程序,重新啓動進程,如果它停止,掛起或沒有響應

我可以使用System.Diagnostics檢測CPU時間增量在60秒內是否爲0(因爲進程通常爲25-30s,cpu使用率爲〜50%),但是當進程閒置資源時可能導致不必要的重新啓動(因爲它的查詢密集型步驟可以持續10分鐘到2小時)。

那麼如何檢測程序是否正在等待mssql查詢或網絡資源,以及/或者我該如何檢測並執行如下所示的內容:http://msdn.microsoft.com/en-us/library/aa373347.aspx

這裏是什麼,我用一個簡化的例子:

 //every 60 seconds 

     Process[] procs; 
     procs = Process.GetProcessesByName(appName); 
     List<int> pidsRunning = new List<int>(); 

     foreach(Process p in procs){ 
      pidsRunning.add(p.id);     
      //other gathering of data and command line arguments 
     } 

     foreach(int pid in pidsLast){ 
      if(!pidsRunning.Contains(pid)){ 
        //do stuff if not running 
      } 
     } 

     pidsRunning = pidsLast; 

UPDATE


我曾嘗試使用p.responding但在我的情況下,它被設置爲真正即使應用程序已發生錯誤:

Program has stopped responding 
details: 

Problem signature: 
    Problem Event Name: APPCRASH 
    Application Name: app.exe 
    Application Version: 1.0.0.0 
    Application Timestamp: 500efec6 
    Fault Module Name: mshtml.dll 
    Fault Module Version: 8.0.7600.17267 
    Fault Module Timestamp: 5131882e 
    Exception Code: c0000005 
    Exception Offset: 00429796 
    OS Version: 6.1.7600.2.0.0.274.10 
    Locale ID: 1033 
    Additional Information 1: 0a9e 
    Additional Information 2: 0a9e372d3b4ad19135b953a78882e789 
    Additional Information 3: 0a9e 
    Additional Information 4: 0a9e372d3b4ad19135b953a78882e789 

這裏是同一個程序的進程對象:

-  p {System.Diagnostics.Process (app)} System.Diagnostics.Process 
-  base {System.Diagnostics.Process (app)} System.ComponentModel.Component {System.Diagnostics.Process} 
+  base {System.Diagnostics.Process (app)} System.MarshalByRefObject {System.Diagnostics.Process} 
     Container null System.ComponentModel.IContainer 
     Site null System.ComponentModel.ISite 
+  Static members  
+  Non-Public members  
     BasePriority 8 int 
     EnableRaisingEvents false bool 
+  ExitCode 'p.ExitCode' threw an exception of type 'System.InvalidOperationException' int {System.InvalidOperationException} 
+  ExitTime 'p.ExitTime' threw an exception of type 'System.InvalidOperationException' System.DateTime {System.InvalidOperationException} 
+  Handle 2368 System.IntPtr 
     HandleCount 614 int 
     HasExited false bool 
     Id 4148 int 
     MachineName "." string 
+  MainModule {System.Diagnostics.ProcessModule (app.exe)} System.Diagnostics.ProcessModule 
+  MainWindowHandle 1771888 System.IntPtr 
     MainWindowTitle "C:\\app.exe" string 
+  MaxWorkingSet 1413120 System.IntPtr 
+  MinWorkingSet 204800 System.IntPtr 
+  Modules {System.Diagnostics.ProcessModuleCollection} System.Diagnostics.ProcessModuleCollection 
     NonpagedSystemMemorySize 59684 int 
     NonpagedSystemMemorySize64 59684 long 
     PagedMemorySize 63553536 int 
     PagedMemorySize64 63553536 long 
     PagedSystemMemorySize 490456 int 
     PagedSystemMemorySize64 490456 long 
     PeakPagedMemorySize 69619712 int 
     PeakPagedMemorySize64 69619712 long 
     PeakVirtualMemorySize 386330624 int 
     PeakVirtualMemorySize64 386330624 long 
     PeakWorkingSet 91586560 int 
     PeakWorkingSet64 91586560 long 
     PriorityBoostEnabled true bool 
     PriorityClass Normal System.Diagnostics.ProcessPriorityClass 
     PrivateMemorySize 63553536 int 
     PrivateMemorySize64 63553536 long 
+  PrivilegedProcessorTime {00:00:20.7793332} System.TimeSpan 
     ProcessName "app" string 
+  ProcessorAffinity 255 System.IntPtr 
     Responding true bool 
     SessionId 2 int 
+  StandardError 'p.StandardError' threw an exception of type 'System.InvalidOperationException' System.IO.StreamReader {System.InvalidOperationException} 
+  StandardInput 'p.StandardInput' threw an exception of type 'System.InvalidOperationException' System.IO.StreamWriter {System.InvalidOperationException} 
+  StandardOutput 'p.StandardOutput' threw an exception of type 'System.InvalidOperationException' System.IO.StreamReader {System.InvalidOperationException} 
+  StartInfo {System.Diagnostics.ProcessStartInfo} System.Diagnostics.ProcessStartInfo 
+  StartTime {10/5/2013 2:19:53 PM} System.DateTime 
     SynchronizingObject null System.ComponentModel.ISynchronizeInvoke 
+  Threads {System.Diagnostics.ProcessThreadCollection} System.Diagnostics.ProcessThreadCollection 
+  TotalProcessorTime {00:07:39.5633459} System.TimeSpan 
+  UserProcessorTime {00:07:18.7840127} System.TimeSpan 
     VirtualMemorySize 378003456 int 
     VirtualMemorySize64 378003456 long 
     WorkingSet 88723456 int 
     WorkingSet64 88723456 long 
+  Static members  
-  Non-Public members  
+  base {System.Diagnostics.Process (app)} System.ComponentModel.Component {System.Diagnostics.Process} 
     Associated true bool 
     disposed false bool 
     error null System.Diagnostics.AsyncStreamReader 
     ErrorDataReceived null System.Diagnostics.DataReceivedEventHandler 
     errorStreamReadMode undefined System.Diagnostics.Process.StreamReadMode 
     exitCode 259 int 
     exited false bool 
+  exitTime {1/1/0001 12:00:00 AM} System.DateTime 
     haveExitTime false bool 
     haveMainWindow true bool 
     havePriorityBoostEnabled true bool 
     havePriorityClass true bool 
     haveProcessHandle true bool 
     haveProcessId true bool 
     haveProcessorAffinity true bool 
     haveResponding false bool 
     haveWorkingSetLimits true bool 
     isRemoteMachine false bool 
     m_processAccess 2035711 int 
+  m_processHandle {Microsoft.Win32.SafeHandles.SafeProcessHandle} Microsoft.Win32.SafeHandles.SafeProcessHandle 
     machineName "." string 
     mainWindowHandle 1771888 System.IntPtr 
     mainWindowTitle "C:\\app.exe" string 
     maxWorkingSet 1413120 System.IntPtr 
     minWorkingSet 204800 System.IntPtr 
+  modules {System.Diagnostics.ProcessModuleCollection} System.Diagnostics.ProcessModuleCollection 
     onExited null System.EventHandler 
+  OperatingSystem {Microsoft Windows NT 6.1.7600.0} System.OperatingSystem 
+  operatingSystem {Microsoft Windows NT 6.1.7600.0} System.OperatingSystem 
     output null System.Diagnostics.AsyncStreamReader 
     OutputDataReceived null System.Diagnostics.DataReceivedEventHandler 
     outputStreamReadMode undefined System.Diagnostics.Process.StreamReadMode 
     pendingErrorRead false bool 
     pendingOutputRead false bool 
     priorityBoostEnabled true bool 
     priorityClass Normal System.Diagnostics.ProcessPriorityClass 
     processId 4148 int 
     processInfo {System.Diagnostics.ProcessInfo} System.Diagnostics.ProcessInfo 
     processorAffinity 255 System.IntPtr 
     raisedOnExited false bool 
     registeredWaitHandle null System.Threading.RegisteredWaitHandle 
     responding true bool 
     signaled false bool 
     standardError null System.IO.StreamReader 
     standardInput null System.IO.StreamWriter 
     standardOutput null System.IO.StreamReader 
-  startInfo {System.Diagnostics.ProcessStartInfo} System.Diagnostics.ProcessStartInfo 
     Arguments "" string 
     CreateNoWindow false bool 
     Domain "" string 
+  EnvironmentVariables {System.Collections.Specialized.StringDictionaryWithComparer} System.Collections.Specialized.StringDictionary {System.Collections.Specialized.StringDictionaryWithComparer} 
     ErrorDialog false bool 
+  ErrorDialogParentHandle 0 System.IntPtr 
     FileName "" string 
     LoadUserProfile false bool 
+  Password null System.Security.SecureString 
     RedirectStandardError false bool 
     RedirectStandardInput false bool 
     RedirectStandardOutput false bool 
+  StandardErrorEncoding null System.Text.Encoding 
+  StandardOutputEncoding null System.Text.Encoding 
     UserName "" string 
     UseShellExecute true bool 
     Verb "" string 
     Verbs {string[0]} string[] 
     WindowStyle Normal System.Diagnostics.ProcessWindowStyle 
     WorkingDirectory "" string 
+  Non-Public members  
     synchronizingObject null System.ComponentModel.ISynchronizeInvoke 
-  threads {System.Diagnostics.ProcessThreadCollection} System.Diagnostics.ProcessThreadCollection 
-  base {System.Diagnostics.ProcessThreadCollection} System.Collections.ReadOnlyCollectionBase {System.Diagnostics.ProcessThreadCollection} 
     Count 36 int 
-  Non-Public members  
+  [System.Diagnostics.ProcessThreadCollection] {System.Diagnostics.ProcessThreadCollection} System.Diagnostics.ProcessThreadCollection 
+  InnerList Count = 36 System.Collections.ArrayList 
+  list Count = 36 System.Collections.ArrayList 
     System.Collections.ICollection.IsSynchronized false bool 
     System.Collections.ICollection.SyncRoot {object} object 
     waitHandle null System.Threading.WaitHandle 
     watchForExit false bool 
     watchingForExit false bool 
+2

該程序是否暴露了API或COM接口?如果是這樣,你可以嘗試調用它,看看你是否及時得到了有效的答覆。我不知道有什麼方法可以從外部準確地判斷另一個程序狀態 - 並且每種類型的問題都需要特定的檢測機制(無限循環,OOM,模式對話等) – Basic

+0

API或COM,不知道,有沒有一個簡單的方法來找出? –

+1

簡而言之,並不是真的 - 對於COM [你需要知道](http://stackoverflow.com/a/2681468/156755)和一個Api可能會以許多不同的方式暴露出來。這就是說,如果你不知道一個Api,它可能沒有一個 – Basic

回答

2
Process[] procs; 
procs = Process.GetProcessesByName(appName); 
bool restartRequired = false; 
foreach (Process proc in procs) { 
    if (!proc.Responding) { 
     restartRequired = true; 
     proc.Kill(); 
     break; 
    } 
} 

if (restartRequired) { 
    Process procRun = new Process(); 
    procRun.StartInfo.FileName = @"C:\Program Files\Winword.exe" 
    procRun.Start(); 
} 
+1

這將檢測如果Windows認爲應用程序正在響應(通常,只是它有一個正在運行的消息泵),但不會抓住所有問題。這就是說,這是對OP的方法的改進,所以+1 – Basic

+0

聽起來不錯,如果不完整,至少是安全的。我會嘗試一下。 –

+0

不幸的是,它不工作在我的情況下,程序正在響應或它具有'respon' = true,它是一個cmd界面應用程序,它有一個錯誤:'問題事件名稱:\t APPCRASH,故障模塊版本:\t 8.0.7600.17267 故障模塊時間戳:\t 5131882e 異常代碼:異常偏移: OS版本:\t 6.1.7600.2.0.0.274.10 區域設置ID:其他信息1:\t 0a9e 其他信息2:\t 0a9e372d3b4ad19135b953a78882e789 其他信息3:\t 0a9e 附加信息4:\t 0a9e372d3b4ad19135b953a78882e789' –

0

有很多,你可以用你的應用實驗方法。試試下面的兩個

System.Reflection.Assembly app = System.Reflection.Assembly.LoadFrom("c:\\Windows\\ConsoleApp.exe"); 
Type[] types = app.GetTypes(); 
foreach (Type type in types) 
{ 
    System.Reflection.MethodInfo method = type.GetMethod("Main", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); 
    if (method != null) 
    { 
    tryAgain: 

     try 
     { 
      method.Invoke(null, null); 
     } 
     catch (Exception ex) 
     { 
      System.Threading.Thread.Sleep(2000); // Wait for 2 seconds if u wish.. 
      goto tryAgain; 
     } 
     break; 
    } 
} 

而且,

void init() 
{ 
    loadProcess(); 
} 

void loadProcess() 
{ 
    System.Threading.Thread.Sleep(2000); 
    System.Diagnostics.Process prc = new System.Diagnostics.Process(); 
    prc.StartInfo.FileName = "C:\\Windows\\ConsoleApp.exe"; 
    prc.Exited += new EventHandler(prc_Exited); // Event Handler when the process is exited. (Mostly not working 4 me) 
    prc.Start(); 
} 

void prc_Exited(object sender, EventArgs e) 
{ 
    loadProcess();  
} 
+0

prc.Exited不會不幸工作:)過程對象('p')表明它仍在運行。 –

+0

您是否嘗試過使用VB6外殼程序執行任何操作? – Sayka

+0

我可以試試嗎? – Sayka

0

既然你後的實際情況是由你可以設置自定義的應用程序作爲JIT調試未處理的異常的APPCRASH,看這裏:

http://msdn.microsoft.com/en-us/library/vstudio/5hs4b7a6.aspx

您的自定義/更換JIT調試器會檢查崩潰的應用程序是你正在看一個,如果是重新啓動它,如果沒有,然後傳遞給真正的JIT調試器。

相關問題