Я знаю, как генерировать файлы Дампа Катастрофического отказа с ADPlus или DebugDiag, но я задаюсь вопросом, существует ли способ сделать это на компьютере клиента, не устанавливая эти инструменты... а именно, я хотел бы иметь возможность настроить свое приложение (использующий значение реестра, например) для генерации дампа катастрофического отказа в случае критического отказа. Строго говоря, я должен быть в состоянии сделать это из приложения C#, но я не возражаю против P/Invoke'ing при необходимости. Спасибо!
Я использую эти написанные мной макросы для создания общих связанных списков. Вы просто создаете свою собственную структуру и используете макрос list_link
где-нибудь как член структуры. Дайте этому макросу один аргумент, называющий структуру (без ключевого слова struct
). Это реализует двусвязный список без фиктивного узла (например, последний узел связывается обратно с первым узлом). Якорь - это указатель на первый узел, который начинается с инициализации list_init (якорь)
путем присвоения ему lvalue (разыменованный указатель на него - это lvalue). Затем вы можете использовать другие макросы в заголовке. Прочтите источник для комментариев о каждой доступной функции макроса. Это на 100% реализовано в макросах.
http://phil.ipal.org/pre-release/list-0.0.5.tar. NET от Джона Роббинса ). Вы даже можете пойти так далеко, чтобы поместить внешний двоичный файл в ресурсы вашего приложения, извлечь его оттуда при запуске (чтобы свести к минимуму сбои в критических ситуациях) на диск (если вы осмелитесь).
Вы можете P / Invoke dbghelp.dll
Функция MiniDumpWriteDump
в событии AppDomain.UnhandledException
.
В этом случае вы можете выгрузить журнал данных исключения .NET и записать минидамп в файл.
Также есть ветка на форумах MSDN , в которой описывается подпись P / Invoke и ее правильное использование.
В зависимости от того, какая информация вам нужна, вы можете добавить обработчик для события AppDomain.UnhandledException
? (Я знаю, что это не совсем то, что вы ищете, но определенно доступно на клиентских машинах.)
Используете ли вы среду ведения журналов, такую как log4net? Обычно вы отключаете сообщения уровня отладки для выпуска. Однако вы можете подумать о написании специального приложения, которое регистрирует файл только в определенных случаях (например, при сбое). Этот аппендер сначала записывает данные в кольцевой буфер только для памяти, который может быть записан в файл, позже - запускается, например, обработчиком исключений, как предложено в 280Z28.
Я думаю, что если ваше приложение закрыто, вы можете попробовать создать мини-файл дампа. Что может случиться хуже всего, ваше приложение выйдет из строя? Он все равно так поступает, так что вы можете попробовать.
Код на форуме MSDN, упомянутый VoiDed , кажется довольно надежным. Мне нужна была версия VB.Net, так что вот версия VB для всех, кому она может понадобиться:
Friend Class MiniDump
'Code converted from C# code found here: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/6c8d3529-a493-49b9-93d7-07a3a2d715dc
Private Enum MINIDUMP_TYPE
MiniDumpNormal = 0
MiniDumpWithDataSegs = 1
MiniDumpWithFullMemory = 2
MiniDumpWithHandleData = 4
MiniDumpFilterMemory = 8
MiniDumpScanMemory = 10
MiniDumpWithUnloadedModules = 20
MiniDumpWithIndirectlyReferencedMemory = 40
MiniDumpFilterModulePaths = 80
MiniDumpWithProcessThreadData = 100
MiniDumpWithPrivateReadWriteMemory = 200
MiniDumpWithoutOptionalData = 400
MiniDumpWithFullMemoryInfo = 800
MiniDumpWithThreadInfo = 1000
MiniDumpWithCodeSegs = 2000
End Enum
<Runtime.InteropServices.DllImport("dbghelp.dll")> _
Private Shared Function MiniDumpWriteDump( _
ByVal hProcess As IntPtr, _
ByVal ProcessId As Int32, _
ByVal hFile As IntPtr, _
ByVal DumpType As MINIDUMP_TYPE, _
ByVal ExceptionParam As IntPtr, _
ByVal UserStreamParam As IntPtr, _
ByVal CallackParam As IntPtr) As Boolean
End Function
Friend Shared Sub MiniDumpToFile(ByVal fileToDump As String)
Dim fsToDump As IO.FileStream = Nothing
If (IO.File.Exists(fileToDump)) Then
fsToDump = IO.File.Open(fileToDump, IO.FileMode.Append)
Else
fsToDump = IO.File.Create(fileToDump)
End If
Dim thisProcess As Process = Process.GetCurrentProcess()
MiniDumpWriteDump(thisProcess.Handle, _
thisProcess.Id, _
fsToDump.SafeFileHandle.DangerousGetHandle(), _
MINIDUMP_TYPE.MiniDumpNormal, _
IntPtr.Zero, _
IntPtr.Zero, _
IntPtr.Zero)
fsToDump.Close()
End Sub
End Class
Просто убедитесь, что вы надежно обрабатываете ее вызовы, и вы должны быть в относительной безопасности.