Скопируйте слой, затем используют shift
+ ctrl
+ v
для создания нового изображения из скопированного слоя.
Используйте этот код для определения структуры с объединением в 32 бита:
[StructLayout(LayoutKind.Explicit)]
internal struct MINIDUMP_CALLBACK_INPUT
{
[FieldOffset(0)]
UInt32 ProcessId;
[FieldOffset(4)]
IntPtr ProcessHandle;
[FieldOffset(8)]
UInt32 CallbackType;
[FieldOffset(12)]
MINIDUMP_THREAD_CALLBACK Thread;
[FieldOffset(12)]
MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
[FieldOffset(12)]
MINIDUMP_MODULE_CALLBACK Module;
[FieldOffset(12)]
MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
[FieldOffset(12)]
MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
};
Я думаю, что на 64-битной платформе смещения должны быть соответственно {0, 8, 16, 24} или {0, 4, 12, 16}, является ли ULONG 64 или 32-битным.
Edit
Я думаю, вы можете использовать MarshalAsAttribute для конкретного преобразования полей:
[StructLayout(LayoutKind.Sequential)]
struct VS_FIXEDFILEINFO
{
UInt32 dwSignature;
UInt32 dwStrucVersion;
UInt32 dwFileVersionMS;
UInt32 dwFileVersionLS;
UInt32 dwProductVersionMS;
UInt32 dwProductVersionLS;
UInt32 dwFileFlagsMask;
UInt32 dwFileFlags;
UInt32 dwFileOS;
UInt32 dwFileType;
UInt32 dwFileSubtype;
UInt32 dwFileDateMS;
UInt32 dwFileDateLS;
}
[StructLayout (LayoutKind.Sequential)]
struct MINIDUMP_MODULE_CALLBACK
{
[MarshalAs(UnmanagedType.LPWStr)]
String FullPath;
UInt64 BaseOfImage;
UInt32 SizeOfImage;
UInt32 CheckSum;
UInt32 TimeDateStamp;
VS_FIXEDFILEINFO VersionInfo;
IntPtr CvRecord;
UInt32 SizeOfCvRecord;
IntPtr MiscRecord;
UInt32 SizeOfMiscRecord;
}
Это не прямой ответ на ваш вопрос, а обходной путь ...
Знаете ли вы библиотеку ClrDump , которая делает что вам нужно ? Я использовал его для проекта несколько лет назад, и он мне подходит.
Ответ на комментарий автора :
Прочтите на сайте:
ClrDump может создавать небольшие минидампы, содержащие достаточно информации для восстановления стеков вызовов всех потоков в приложении.
Я заключил API в следующий класс:
internal class ClrDump
{
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("clrdump.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool CreateDump(uint ProcessId, string FileName, MINIDUMP_TYPE DumpType, uint ExcThreadId, IntPtr ExtPtrs);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("clrdump.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool RegisterFilter(string FileName, MINIDUMP_TYPE DumpType);
[DllImport("clrdump.dll")]
public static extern FILTER_OPTIONS SetFilterOptions(FILTER_OPTIONS Options);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("clrdump.dll", SetLastError=true)]
public static extern bool UnregisterFilter();
[Flags]
public enum FILTER_OPTIONS
{
CLRDMP_OPT_CALLDEFAULTHANDLER = 1
}
[Flags]
public enum MINIDUMP_TYPE
{
MiniDumpFilterMemory = 8,
MiniDumpFilterModulePaths = 0x80,
MiniDumpNormal = 0,
MiniDumpScanMemory = 0x10,
MiniDumpWithCodeSegs = 0x2000,
MiniDumpWithDataSegs = 1,
MiniDumpWithFullMemory = 2,
MiniDumpWithFullMemoryInfo = 0x800,
MiniDumpWithHandleData = 4,
MiniDumpWithIndirectlyReferencedMemory = 0x40,
MiniDumpWithoutManagedState = 0x4000,
MiniDumpWithoutOptionalData = 0x400,
MiniDumpWithPrivateReadWriteMemory = 0x200,
MiniDumpWithProcessThreadData = 0x100,
MiniDumpWithThreadInfo = 0x1000,
MiniDumpWithUnloadedModules = 0x20
}
}
, а затем где-то в моем коде инициализации я вызвал метод RegisterFilter, который регистрирует внутренний фильтр для необработанных исключений в текущем процессе. Если процесс вылетает из-за необработанного исключения (это может быть собственное или управляемое исключение), фильтр перехватывает его и создает минидамп (с указанным именем файла). Вот пример кода для этого:
StringBuilder sb = new StringBuilder();
sb.Append(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
sb.Append("_");
sb.Append(DateTime.Now.ToString("yyyyMMddHHmmssFF"));
sb.Append(".dmp");
string dmpFilePath = Path.Combine(Path.GetTempPath(), sb.ToString());
ClrDump.RegisterFilter(_dmpFilePath, ClrDump.MINIDUMP_TYPE.MiniDumpNormal);
Вы можете прочитать эту статью , чтобы понять различные параметры MINIDUMP_TYPE, но я думаю, что базовый вариант (MiniDumpNormal) может удовлетворить ваши потребности.
Я вызвал метод RegisterFilter, который регистрирует внутренний фильтр для необработанных исключений в текущем процессе. Если процесс вылетает из-за необработанного исключения (это может быть собственное или управляемое исключение), фильтр перехватывает его и создает минидамп (с указанным именем файла). Вот пример кода для этого:StringBuilder sb = new StringBuilder();
sb.Append(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
sb.Append("_");
sb.Append(DateTime.Now.ToString("yyyyMMddHHmmssFF"));
sb.Append(".dmp");
string dmpFilePath = Path.Combine(Path.GetTempPath(), sb.ToString());
ClrDump.RegisterFilter(_dmpFilePath, ClrDump.MINIDUMP_TYPE.MiniDumpNormal);
Вы можете прочитать эту статью , чтобы понять различные параметры MINIDUMP_TYPE, но я думаю, что базовый вариант (MiniDumpNormal) может удовлетворить ваши потребности.
Я вызвал метод RegisterFilter, который регистрирует внутренний фильтр для необработанных исключений в текущем процессе. Если процесс вылетает из-за необработанного исключения (это может быть собственное или управляемое исключение), фильтр перехватывает его и создает минидамп (с указанным именем файла). Вот пример кода для этого:StringBuilder sb = new StringBuilder();
sb.Append(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
sb.Append("_");
sb.Append(DateTime.Now.ToString("yyyyMMddHHmmssFF"));
sb.Append(".dmp");
string dmpFilePath = Path.Combine(Path.GetTempPath(), sb.ToString());
ClrDump.RegisterFilter(_dmpFilePath, ClrDump.MINIDUMP_TYPE.MiniDumpNormal);
Вы можете прочитать эту статью , чтобы понять различные параметры MINIDUMP_TYPE, но я думаю, что базовый вариант (MiniDumpNormal) может удовлетворить ваши потребности.
Я так понимаю, что это союз, который доставляет вам проблемы ?
Если CallbackType == KernelMinidumpStatusCallback, то структура CALLBACK_INPUT определяется как:
ULONG ProcessId;
HANDLE ProcessHandle;
ULONG CallbackType;
HRESULT Status;
Если CallbackType == ThreadCallback, то это:
ULONG ProcessId;
HANDLE ProcessHandle;
ULONG CallbackType;
MINIDUMP_THREAD_CALLBACK Thread;
Если CallbackType == ThreadExCallback, то это:
ULONG ProcessId;
HANDLE ProcessHandle;
ULONG CallbackType;
MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
И так далее (это из MSDN ) - похоже, что 4-й член может быть одного из 8 различных типов, в зависимости от того, чему равен CallbackType. Внутри Windows будет использовать один и тот же кусок памяти для всех этих структур (добавляя меньшие к размеру наибольшего). В C ++ легко получить нужный тип
Я не знаю, как это сделать на C #. Я использовал MiniDumpWriteDump в C ++, но никогда не использовал функцию обратного вызова.