程序挂起时自动创建转储文件

目录

介绍

背景

使用代码


介绍

我想知道当我的程序因意外异常而挂起时如何自动创建转储文件。

背景

有很多关于如何使用Window Command或Windbg程序创建转储文件的文章。

但是我的程序已经被设置为客户的计算机,所以我不能告诉他“当程序没有响应时你应该自己制作一个转储文件。

使用代码

要运行此程序,您需要使用cdb.exe文件。您可以在附件文件中找到。或者您可以在互联网上将其下载为“Windows软件开发工具包”。安装时,应检查“Debuggin Tools for Windows”项。这些文件包括在内。您也可以使用windbg.exe文件而不是cdb.exe。如果你使用它,windbg窗口将打开并运行。

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ProcessHangCheck
{
    public partial class Form1 : Form
    {
        Thread mThread;
        Process mProcess;

        public Form1()
        {
            InitializeComponent();
            mThread = null;
            mProcess = null;
        }

        // start monitoring 
        private void button1_Click(object sender, EventArgs e)
        {
            // process name except for ".exe"
            String strProcName = txtProcName.Text;

            // the execution file which is place in (like cdb or windbg)
            String strDumpExePath = txtDumpExecutionPath.Text;

            // the directory place in which a dump file is created
            String strDumpPath = txtDumpPath.Text;

            try
            {
                strDumpExePath = Path.GetFullPath(strDumpExePath);
                strDumpPath = Path.GetFullPath(strDumpPath);

                if (!Directory.Exists(strDumpExePath))
                    Directory.CreateDirectory(strDumpExePath);

                if (!Directory.Exists(strDumpPath))
                    Directory.CreateDirectory(strDumpPath);
            }
            catch (Exception)
            {
                strDumpExePath = "";
                strDumpPath = "";
            }

            if (String.IsNullOrEmpty(strProcName) ||
                String.IsNullOrEmpty(strDumpExePath) ||
                String.IsNullOrEmpty(strDumpPath))
            {
                MessageBox.Show("Process Name or CDB's location or Dump's directory is empty.");
            }
            else
            {
                Stop();
                mThread = new Thread(() => threadMain(strProcName, strDumpExePath, strDumpPath));
                mThread.Start();
            }
        }

        private void threadMain(String strProcName, String strDumpExePath, String strDumpPath)
        {
            if (String.IsNullOrEmpty(strProcName) || 
                String.IsNullOrEmpty(strDumpExePath) || String.IsNullOrEmpty(strDumpPath)) return;

            bool isAbort = false;
            while (!isAbort)
            {
                try
                {
                    Process[] procs = Process.GetProcessesByName(strProcName);
                    if (procs.Length != 0)
                    {
                        foreach (Process pr in procs)
                        {
                            // if this process is hanging
                            if (!pr.Responding)
                            {
                                Console.WriteLine("Start trying to create a dumpfile");

                                try
                                {
                                    strDumpExePath += "\\";
                                    strDumpExePath = Path.GetFullPath(strDumpExePath);

                                    strDumpPath += "\\";
                                    strDumpPath = Path.GetFullPath(strDumpPath);

                                    String strCmdParam = String.Format(
                                            "-p {0} -c \".dump /o /ma {1}{2}.dmp\"",
                                            pr.Id,
                                            strDumpPath,
                                            DateTime.Now.ToString("yyyyMMddHHmmss"));
                                    Console.WriteLine(strCmdParam);

                                    mProcess = new Process();

                                    mProcess.StartInfo.FileName = "cmd.exe";
                                    mProcess.StartInfo.UseShellExecute = false;
                                    mProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                                    mProcess.StartInfo.CreateNoWindow = true;
                                    mProcess.StartInfo.RedirectStandardOutput = true;
                                    mProcess.StartInfo.RedirectStandardInput = true;
                                    mProcess.StartInfo.RedirectStandardError = true;
                                    mProcess.Start();
                                    mProcess.StandardInput.WriteLine(
                                        String.Format(
                                            "\"{0}cdb.exe\" -p {1} -c \".dump /o /ma {2}{3}.dmp\"{4}",
                                            strDumpExePath,
                                            pr.Id,
                                            strDumpPath,
                                            DateTime.Now.ToString("yyyyMMddHHmmss"),
                                            Environment.NewLine));

                                    mProcess.StandardInput.Close();
                                    String strOutput = mProcess.StandardOutput.ReadToEnd();
                                    Console.WriteLine(strOutput);

                                    mProcess.WaitForExit(10 * 1000);
                                    if (!mProcess.HasExited) mProcess.Kill();

                                    if (!pr.HasExited) pr.Kill();
                                }
                                catch(Exception ex)
                                {
                                    MessageBox.Show(ex.ToString());
                                }
                            }
                            else
                            {
                                Console.WriteLine("Noting to do");
                            }
                        }
                    }
                    else
                        Console.WriteLine("Process isn't running");

                    Thread.Sleep(10 * 1000);
                }
                catch(ThreadAbortException)
                {
                    isAbort = true;
                    Thread.ResetAbort();
                }
                catch (Exception ee)
                {
                    Console.WriteLine(ee.ToString());
                    Thread.Sleep(10 * 1000);
                }
            }
        }

        private void Stop()
        {
            try
            {
                if (mThread != null)
                    mThread.Abort();

                if (mProcess != null && !mProcess.HasExited)
                    mProcess.Kill();
            }
            catch (Exception) { }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Stop();
        }

        // stop monitoring
        private void button2_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            String strRoot = Application.StartupPath;
            txtDumpExecutionPath.Text = String.Format("{0}\\USEEXE", strRoot);
        }
    }
}

原文地址:https://www.codeproject.com/Tips/1275304/Automatically-Create-Dump-File-When-Program-Hangs

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值