From 1020f8a85bea7fe37c33f2f856cae03895bf5749 Mon Sep 17 00:00:00 2001 From: marzent Date: Thu, 15 Feb 2024 23:39:08 +0100 Subject: [PATCH] add progress dialog to crash handler --- DalamudCrashHandler/DalamudCrashHandler.cpp | 49 +++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp index 4e2f01708..258ec923d 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.cpp +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #pragma comment(lib, "comctl32.lib") @@ -670,6 +671,7 @@ int main() { std::filesystem::path assetDir, logDir; std::optional> launcherArgs; auto fullDump = false; + CoInitializeEx(nullptr, COINIT_MULTITHREADED); std::vector args; if (int argc = 0; const auto argv = CommandLineToArgvW(GetCommandLineW(), &argc)) { @@ -753,6 +755,35 @@ int main() { std::cout << "Crash triggered" << std::endl; + std::cout << "Creating progress window" << std::endl; + IProgressDialog* pProgressDialog = NULL; + if (SUCCEEDED(CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_ALL, IID_IProgressDialog, (void**)&pProgressDialog)) && pProgressDialog) { + pProgressDialog->SetTitle(L"Dalamud"); + pProgressDialog->SetLine(1, L"The game has crashed", FALSE, NULL); + pProgressDialog->SetLine(2, L"Dalamud is collecting further information", FALSE, NULL); + pProgressDialog->SetLine(3, L"Refreshing Game Module List", FALSE, NULL); + pProgressDialog->StartProgressDialog(NULL, NULL, PROGDLG_MARQUEEPROGRESS | PROGDLG_NOCANCEL | PROGDLG_NOMINIMIZE, NULL); + IOleWindow* pOleWindow; + HRESULT hr = pProgressDialog->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow); + if (SUCCEEDED(hr)) + { + HWND hwndProgressDialog = NULL; + hr = pOleWindow->GetWindow(&hwndProgressDialog); + if (SUCCEEDED(hr)) + { + SetWindowPos(hwndProgressDialog, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + + pOleWindow->Release(); + } + + } + else { + std::cerr << "Failed to create progress window" << std::endl; + pProgressDialog = NULL; + } + auto shutup_mutex = CreateMutex(NULL, false, L"DALAMUD_CRASHES_NO_MORE"); bool shutup = false; if (shutup_mutex == NULL && GetLastError() == ERROR_ALREADY_EXISTS) @@ -791,6 +822,9 @@ int main() { std::wcerr << std::format(L"SymInitialize error: 0x{:x}", GetLastError()) << std::endl; } + if (pProgressDialog) + pProgressDialog->SetLine(3, L"Reading troubleshooting data", FALSE, NULL); + std::wstring stackTrace(exinfo.dwStackTraceLength, L'\0'); if (exinfo.dwStackTraceLength) { if (DWORD read; !ReadFile(hPipeRead, &stackTrace[0], 2 * exinfo.dwStackTraceLength, &read, nullptr)) { @@ -805,6 +839,9 @@ int main() { } } + if (pProgressDialog) + pProgressDialog->SetLine(3, fullDump ? L"Creating full dump" : L"Creating minidump", FALSE, NULL); + SYSTEMTIME st; GetLocalTime(&st); const auto dalamudLogPath = logDir.empty() ? std::filesystem::path() : logDir / L"Dalamud.log"; @@ -857,6 +894,9 @@ int main() { log << L"System Time: " << std::chrono::system_clock::now() << std::endl; log << L"\n" << stackTrace << std::endl; + if (pProgressDialog) + pProgressDialog->SetLine(3, L"Refreshing Module List", FALSE, NULL); + SymRefreshModuleList(GetCurrentProcess()); print_exception_info(exinfo.hThreadHandle, exinfo.ExceptionPointers, exinfo.ContextRecord, log); const auto window_log_str = log.str(); @@ -993,11 +1033,20 @@ int main() { }; config.lpCallbackData = reinterpret_cast(&callback); + if (pProgressDialog) + pProgressDialog->SetLine(3, L"Submitting Metrics", FALSE, NULL); + if (submitThread.joinable()) { submitThread.join(); submitThread = {}; } + if (pProgressDialog) { + pProgressDialog->StopProgressDialog(); + pProgressDialog->Release(); + pProgressDialog = NULL; + } + if (shutup) { TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode); return 0;