目录
介绍
背景
使用代码
介绍我想知道当我的程序因意外异常而挂起时如何自动创建转储文件。
背景有很多关于如何使用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