diff --git a/BeefLibs/corlib/src/Platform.bf b/BeefLibs/corlib/src/Platform.bf index 0e983ec6..f6749061 100644 --- a/BeefLibs/corlib/src/Platform.bf +++ b/BeefLibs/corlib/src/Platform.bf @@ -53,6 +53,8 @@ namespace System [CallingConvention(.Stdcall), CLink] public static extern uint32 BfpSystem_TickCount(); [CallingConvention(.Stdcall), CLink] + public static extern uint32 BfpSystem_SetCrashRelaunchCmd(char8* cmd); + [CallingConvention(.Stdcall), CLink] public static extern BfpTimeStamp BfpSystem_GetTimeStamp(); [CallingConvention(.Stdcall), CLink] public static extern uint8 BfpSystem_InterlockedExchange8(uint8* ptr, uint8 val); /// Returns the initial value in 'ptr' diff --git a/BeefySysLib/platform/PlatformInterface.h b/BeefySysLib/platform/PlatformInterface.h index 3a209512..6a36a1f8 100644 --- a/BeefySysLib/platform/PlatformInterface.h +++ b/BeefySysLib/platform/PlatformInterface.h @@ -103,6 +103,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv); BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind); BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc); BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str); // Can do at any time, or during CrashInfoFunc callbacks +BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashRelaunchCmd(const char* str); BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown(); BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount(); BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpSystem_GetTimeStamp(); diff --git a/BeefySysLib/platform/posix/PosixCommon.cpp b/BeefySysLib/platform/posix/PosixCommon.cpp index 82d67553..0d3efb03 100644 --- a/BeefySysLib/platform/posix/PosixCommon.cpp +++ b/BeefySysLib/platform/posix/PosixCommon.cpp @@ -593,6 +593,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str) // Can do a BfpGetGlobalData()->mCrashInfo.Append(str); } +BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashRelaunchCmd(const char* str) +{ +} + void BfpSystem_Shutdown() { diff --git a/BeefySysLib/platform/win/CrashCatcher.cpp b/BeefySysLib/platform/win/CrashCatcher.cpp index 4c04e668..2d7ce4fd 100644 --- a/BeefySysLib/platform/win/CrashCatcher.cpp +++ b/BeefySysLib/platform/win/CrashCatcher.cpp @@ -2,6 +2,7 @@ #include "../util/Dictionary.h" #include #include +#include USING_NS_BF; @@ -192,6 +193,45 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } else if (hwndCtl == gNoButtonWindow) { + if (!CrashCatcher::Get()->mRelaunchCmd.IsEmpty()) + { + SHELLEXECUTEINFOW shellExecuteInfo = { 0 }; + shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW); + shellExecuteInfo.nShow = SW_SHOWNORMAL; + + String cmd = CrashCatcher::Get()->mRelaunchCmd; + String file; + + bool nameQuoted = cmd[0] == '\"'; + + int i; + for (i = (nameQuoted ? 1 : 0); cmd[i] != 0; i++) + { + wchar_t c = cmd[i]; + + if (((nameQuoted) && (c == '"')) || + ((!nameQuoted) && (c == ' '))) + { + i++; + break; + } + file += cmd[i]; + } + + const char* useParamsPtr = cmd.c_str(); + useParamsPtr += i; + while (*useParamsPtr == L' ') + useParamsPtr++; + + auto fileW = UTF8Decode(file); + shellExecuteInfo.lpFile = fileW.c_str(); + auto paramsW = UTF8Decode(useParamsPtr); + shellExecuteInfo.lpParameters = paramsW.c_str(); + + BOOL success = ::ShellExecuteExW(&shellExecuteInfo); + } + + CrashCatcher::Get()->mCloseRequested = true; gExiting = true; } else if (hwndCtl == gDebugButtonWindow) @@ -202,6 +242,7 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_CLOSE: + CrashCatcher::Get()->mCloseRequested = true; gExiting = true; return 0; } @@ -209,7 +250,7 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA return DefWindowProc(hWnd, uMsg, wParam, lParam); } -static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& errorText) +static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& errorText, const StringImpl& relaunchCmd) { bool gUseDefaultFonts; @@ -362,8 +403,8 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro aCurX += aButtonWidth + 8; } - - gNoButtonWindow = CreateWindowA("BUTTON", "Close Now", + + gNoButtonWindow = CreateWindowA("BUTTON", relaunchCmd.IsEmpty() ? "Close Now" : "Relaunch", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_PUSHBUTTON, aCurX, aRect.bottom - 24 - 8, aButtonWidth, @@ -803,9 +844,10 @@ static String GetVersion(const StringImpl& fileName) static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP) { - if (CrashCatcher::Get()->mCrashed) + auto crashCatcher = CrashCatcher::Get(); + if (crashCatcher->mCrashed) return; - CrashCatcher::Get()->mCrashed = true; + crashCatcher->mCrashed = true; HMODULE hMod = GetModuleHandleA(NULL); @@ -983,7 +1025,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP) ::WriteFile(::GetStdHandle(STD_ERROR_HANDLE), aDebugDump.c_str(), (DWORD)aDebugDump.length(), &bytesWritten, NULL); } else - ShowErrorDialog(anErrorTitle, aDebugDump); + ShowErrorDialog(anErrorTitle, aDebugDump, crashCatcher->mRelaunchCmd); } CrashCatcher::CrashCatcher() @@ -994,6 +1036,7 @@ CrashCatcher::CrashCatcher() mPreviousFilter = NULL; mDebugError = false; mCrashReportKind = BfpCrashReportKind_Default; + mCloseRequested = false; } static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr) @@ -1025,7 +1068,8 @@ static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr) ::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode); } - return EXCEPTION_CONTINUE_SEARCH; + //return EXCEPTION_CONTINUE_SEARCH; + return (CrashCatcher::Get()->mCloseRequested) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } //PVECTORED_EXCEPTION_HANDLER( @@ -1121,6 +1165,11 @@ void CrashCatcher::SetCrashReportKind(BfpCrashReportKind crashReportKind) mCrashReportKind = crashReportKind; } +void CrashCatcher::SetRelaunchCmd(const StringImpl& relaunchCmd) +{ + mRelaunchCmd = relaunchCmd; +} + struct CrashCatchMemory { public: diff --git a/BeefySysLib/platform/win/CrashCatcher.h b/BeefySysLib/platform/win/CrashCatcher.h index 8e4c18e5..10e58415 100644 --- a/BeefySysLib/platform/win/CrashCatcher.h +++ b/BeefySysLib/platform/win/CrashCatcher.h @@ -18,7 +18,9 @@ public: EXCEPTION_POINTERS* mExceptionPointers; LPTOP_LEVEL_EXCEPTION_FILTER mPreviousFilter; bool mDebugError; + bool mCloseRequested; BfpCrashReportKind mCrashReportKind; + String mRelaunchCmd; public: CrashCatcher(); @@ -30,6 +32,7 @@ public: virtual void Test(); virtual void Crash(const StringImpl& str); virtual void SetCrashReportKind(BfpCrashReportKind crashReportKind); + virtual void SetRelaunchCmd(const StringImpl& relaunchCmd); static CrashCatcher* Get(); }; diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 9296987b..70ccb986 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -970,6 +970,11 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str) CrashCatcher::Get()->AddInfo(str); } +BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashRelaunchCmd(const char* str) +{ + CrashCatcher::Get()->SetRelaunchCmd(str); +} + BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown() { while (gManagerTail != NULL) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 7eb60500..4a73b3cc 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -2596,6 +2596,14 @@ namespace IDE mBfResolveCompiler.QueueSetWorkspaceOptions(null, 0); #endif + String relaunchCmd = scope .(); + relaunchCmd.Append("\""); + Environment.GetExecutableFilePath(relaunchCmd); + relaunchCmd.Append("\" -workspace=\""); + relaunchCmd.Append(mWorkspace.mDir); + relaunchCmd.Append("\""); + Platform.BfpSystem_SetCrashRelaunchCmd(relaunchCmd); + MarkDirty(); }