/** * This method handles the actual details of saving an assertion report. It will * bring up the "File save as..." dialog and then write the report out to * whichever file the user selects * * \return True if the user saved the file, false if they aborted the action */ bool AssertionDialog::SaveCrashDump() const { bool didSaveFile = false; // Create the file save as dialog Microsoft::WRL::ComPtr<IFileDialog> fileDialog; HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fileDialog)); if (!SUCCEEDED(hr)) { return false; } // File types supported COMDLG_FILTERSPEC filters[] = { { L"Text Files", L"*.txt" } }; // Configure the save dialog with useful defaults fileDialog->SetTitle(L"Save crash dump to a file"); fileDialog->SetFileTypes(ARRAYSIZE(filters), filters); fileDialog->SetDefaultExtension(L"*.txt"); fileDialog->SetFileName(L"crash details.txt"); // Show the file save as dialog fileDialog->Show(mWindowHandle); // Find the name of the file they want to save the assertion report to. // If the user didn't give an appropriate response, simply leave the filename // to be null Microsoft::WRL::ComPtr<IShellItem> dialogResult; PWSTR filepath = nullptr; hr = fileDialog->GetResult(&dialogResult); if (SUCCEEDED(hr)) { HRESULT hr = dialogResult->GetDisplayName(SIGDN_FILESYSPATH, &filepath); if (SUCCEEDED(hr)) { std::string fileContents = Utils::ConvertWideStringToUtf8(GetFileReportString()); // First we have to create the file HANDLE fileHandle = CreateFile( filepath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // Convert the text file to UTF8 and then write the string to disk. WriteFile( fileHandle, fileContents.c_str(), static_cast<DWORD>(fileContents.size()), nullptr, nullptr); // Remember that we wrote the file out didSaveFile = true; } } // Now clean up. Release the dialog window and close the file stream. CoTaskMemFree(filepath); return didSaveFile; }