-
Notifications
You must be signed in to change notification settings - Fork 0
/
MiniDump.cs
117 lines (98 loc) · 3.99 KB
/
MiniDump.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using ProcessDump.Extensions;
using ProcessDump.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace ProcessDump
{
public class MiniDump
{
private static string TempPath = Directory.GetCurrentDirectory();
public static string Create(int processId)
{
return Create(processId, NativeMethods._MINIDUMP_TYPE.MiniDumpNormal);
}
public static string Create(int processId, NativeMethods._MINIDUMP_TYPE dumpType)
{
return Create(processId, dumpType, TempPath);
}
public static string Create(int processId, NativeMethods._MINIDUMP_TYPE dumpType, string path)
{
Process process = Process.GetProcessById(processId);
if (process == null)
{
throw new InvalidOperationException($"Specify a valid process id - {processId} not found.");
}
return Create(process, dumpType, path);
}
public static string Create(string processName)
{
return Create(processName, NativeMethods._MINIDUMP_TYPE.MiniDumpNormal);
}
public static string Create(string processName, NativeMethods._MINIDUMP_TYPE dumpType)
{
Process process = Process.GetProcessesByName(processName).FirstOrDefault();
if (process == null)
{
throw new InvalidOperationException($"Specify a valid process name - {processName} not found.");
}
return Create(process, dumpType, TempPath);
}
public static string Create(Process process, NativeMethods._MINIDUMP_TYPE dumpType, string outputPath)
{
IntPtr hFile = IntPtr.Zero;
if (IntPtr.Size == 4)
{
Console.WriteLine($"CreateMiniDump {dumpType} - Running as 32 bit, creating 32 bit dumps");
}
else
{
Console.WriteLine($"CreateMiniDump {dumpType} - Running as 64 bit, creating 64 bit dumps");
}
try
{
var dumpFileName = $@"{outputPath}\MiniDumpProcess-{dumpType.ToString()}.dmp";
if (File.Exists(dumpFileName))
{
File.Delete(dumpFileName);
}
hFile = NativeMethods.CreateFile(dumpFileName, NativeMethods.EFileAccess.GenericWrite,
NativeMethods.EFileShare.None, lpSecurityAttributes: IntPtr.Zero,
dwCreationDisposition: NativeMethods.ECreationDisposition.CreateAlways,
dwFlagsAndAttributes: NativeMethods.EFileAttributes.Normal, hTemplateFile: IntPtr.Zero
);
if (hFile == NativeMethods.INVALID_HANDLE_VALUE)
{
var hr = Marshal.GetHRForLastWin32Error();
var ex = Marshal.GetExceptionForHR(hr);
throw ex;
}
var exceptInfo = new NativeMethods.MINIDUMP_EXCEPTION_INFORMATION();
if (!process.Is32BitProcess() && IntPtr.Size == 4)
{
throw new InvalidOperationException("Can't create 32 bit dump of 64 bit process");
}
var isDumpWrittenSuccessfully = NativeMethods.MiniDumpWriteDump(process.Handle, process.Id, hFile,
dumpType, ref exceptInfo, UserStreamParam: IntPtr.Zero, CallbackParam: IntPtr.Zero);
if (!isDumpWrittenSuccessfully)
{
var hr = Marshal.GetHRForLastWin32Error();
var ex = Marshal.GetExceptionForHR(hr);
throw ex;
}
return dumpFileName;
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw ex;
}
finally
{
NativeMethods.CloseHandle(hFile);
}
}
}
}