public static extern Int32 PssCaptureSnapshot( IntPtr ProcessHandle, Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS CaptureFlags, Int32 ThreadContextFlags, out IntPtr SnapshotHandle );
/// <summary> /// Creates a snapshot (PssCaptureSnapshot) of a process and dumps it (MiniDumpWriteDump). /// Minimum supported Windows versions: Windows 8.1+ and Windows Server 2012+ /// </summary> /// <param name="process">Process to generate a minidump for.</param> /// <param name="outputPath">Path to write output file in. Defaults to the current directory.</param> /// <param name="outputFileName">Filename to ouput the minidump to.</param> /// <returns>True if snapshut dump succeeds, false otherwise.</returns> /// <remarks> /// Authored by Simone Salucci (@saim1z) and Daniel López (@attl4s). /// Code adapted from https://github.com/b4rtik/SharpMiniDump /// and https://github.com/mjsabby/CopyOnWriteDump /// </remarks> public static bool CreateProcessSnapshotDump(Process process, string outputPath = "", string outputFileName = "") { if (outputPath == "" || outputPath == null) { outputPath = GetCurrentDirectory(); } if (outputFileName == "" || outputFileName == null) { outputFileName = process.ProcessName + "_" + process.Id + ".dmp"; } string fullPath = Path.Combine(outputPath, outputFileName); FileStream fileStream = new FileStream(fullPath, FileMode.Create); IntPtr snapshotHandle; Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS flags = Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_VA_CLONE | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLES | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_NAME_INFORMATION | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_BASIC_INFORMATION | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_TRACE | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_THREADS | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_THREAD_CONTEXT | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CAPTURE_THREAD_CONTEXT_EXTENDED | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CREATE_BREAKAWAY | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CREATE_BREAKAWAY_OPTIONAL | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CREATE_USE_VM_ALLOCATIONS | Execution.Win32.Kernel32.PSS_CAPTURE_FLAGS.PSS_CREATE_RELEASE_SECTION; snapshotHandle = IntPtr.Zero; try { Int32 hr = PInvoke.Win32.Kernel32.PssCaptureSnapshot(process.Handle, flags, IntPtr.Size == 8 ? 0x0010001F : 0x0001003F, out snapshotHandle); } catch (EntryPointNotFoundException e) { Console.Error.WriteLine(e.Message); return(false); } Execution.Win32.Dbghelp.MINIDUMP_CALLBACK_INFORMATION CallbackInfo = new Execution.Win32.Dbghelp.MINIDUMP_CALLBACK_INFORMATION(); CallbackInfo.CallbackRoutine = Host.MiniDumpWriteDumpCallback; CallbackInfo.CallbackParam = IntPtr.Zero; IntPtr pCallbackInfo = Marshal.AllocHGlobal(Marshal.SizeOf(CallbackInfo)); Marshal.StructureToPtr(CallbackInfo, pCallbackInfo, false); bool success = false; try { success = PInvoke.Win32.Dbghelp.MiniDumpWriteDump(snapshotHandle, (uint)process.Id, fileStream.SafeFileHandle, Execution.Win32.Dbghelp.MINIDUMP_TYPE.MiniDumpWithFullMemory, IntPtr.Zero, IntPtr.Zero, pCallbackInfo); } catch (System.ComponentModel.Win32Exception e) { Console.Error.WriteLine(e.Message); } fileStream.Close(); if (!success) { File.Delete(fullPath); } IntPtr vaCloneHandle; PInvoke.Win32.Kernel32.PssQuerySnapshot(snapshotHandle, Execution.Win32.Kernel32.PSS_QUERY_INFORMATION_CLASS.PSS_QUERY_VA_CLONE_INFORMATION, out vaCloneHandle, IntPtr.Size); int cloneProcessId = PInvoke.Win32.Kernel32.GetProcessId(vaCloneHandle); PInvoke.Win32.Kernel32.PssFreeSnapshot(Process.GetCurrentProcess().Handle, snapshotHandle); PInvoke.Win32.Kernel32.CloseHandle(vaCloneHandle); Marshal.FreeHGlobal(pCallbackInfo); GC.KeepAlive(CallbackInfo); return(success); }