2

我正在使用一个开发不佳的应用程序,由于内存泄漏或其他在重新启动后不会重复的随机错误而不断重新启动。我无权访问代码,也无法修复它。

我开发了 ac# 应用程序,它管理重新启动并在程序停止时保持程序运行,但我如何识别挂起(或当它崩溃但 Windows 错误消息使其保持“运行”时)。

我可以System.Diagnostics用来检测 CPU 时间增量在 60 秒内是否为 0(因为进程通常在 25-30 秒,~50%cpu 使用率),但是当进程空闲资源时,这可能会导致不必要的重启(因为它有查询密集型步骤,可持续 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;

更新


我尝试使用,但在我的情况下,即使应用程序抛出错误p.responding,它也设置为true :

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
4

3 回答 3

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();
}
于 2013-10-05T14:10:00.030 回答
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();       
}
于 2013-10-06T18:55:24.000 回答
0

由于您所追求的实际情况是由未处理的异常引起的 APPCRASH,您可以将自定义应用程序设置为 JIT 调试器,请参见此处:

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

您的自定义/替换 JIT 调试器将检查崩溃的应用程序是否是您正在观看的应用程序,如果是,则重新启动它,如果不是,则传递给真正的 JIT 调试器。

于 2013-11-09T22:52:06.087 回答