mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 05:54:23 +00:00
Compare commits
5 Commits
v1.25.1241
...
dev/duhowe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ece1296397 | ||
|
|
8b84e9165f | ||
|
|
ef107fe471 | ||
|
|
6770c8fa81 | ||
|
|
f54b5a93a5 |
@@ -68,7 +68,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||||||
|
|
||||||
void WindowManager::SignalClose()
|
void WindowManager::SignalClose()
|
||||||
{
|
{
|
||||||
if (_monarch)
|
if (_monarch && _peasant)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ static void EnsureAllResourcesArePresent(const ScopedResourceLoader& loader)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ScopedResourceLoader GetLibraryResourceLoader()
|
static ScopedResourceLoader GetLibraryResourceLoader()
|
||||||
try
|
|
||||||
{
|
{
|
||||||
ScopedResourceLoader loader{ g_WinRTUtilsLibraryResourceScope };
|
ScopedResourceLoader loader{ g_WinRTUtilsLibraryResourceScope };
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@@ -85,20 +84,15 @@ try
|
|||||||
#endif
|
#endif
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
CATCH_FAIL_FAST()
|
|
||||||
|
|
||||||
winrt::hstring GetLibraryResourceString(const std::wstring_view key)
|
winrt::hstring GetLibraryResourceString(const std::wstring_view key)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
static auto loader{ GetLibraryResourceLoader() };
|
static auto loader{ GetLibraryResourceLoader() };
|
||||||
return loader.GetLocalizedString(key);
|
return loader.GetLocalizedString(key);
|
||||||
}
|
}
|
||||||
CATCH_FAIL_FAST()
|
|
||||||
|
|
||||||
bool HasLibraryResourceWithName(const std::wstring_view key)
|
bool HasLibraryResourceWithName(const std::wstring_view key)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
static auto loader{ GetLibraryResourceLoader() };
|
static auto loader{ GetLibraryResourceLoader() };
|
||||||
return loader.HasResourceWithName(key);
|
return loader.HasResourceWithName(key);
|
||||||
}
|
}
|
||||||
CATCH_FAIL_FAST()
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ using namespace std::chrono_literals;
|
|||||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||||
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
||||||
|
|
||||||
AppHost::AppHost() noexcept :
|
AppHost::AppHost() :
|
||||||
_app{},
|
_app{},
|
||||||
_windowManager{},
|
_windowManager{},
|
||||||
_logic{ nullptr }, // don't make one, we're going to take a ref on app's
|
_logic{ nullptr }, // don't make one, we're going to take a ref on app's
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
class AppHost
|
class AppHost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AppHost() noexcept;
|
AppHost();
|
||||||
virtual ~AppHost();
|
virtual ~AppHost();
|
||||||
|
|
||||||
void AppTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, winrt::hstring newTitle);
|
void AppTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, winrt::hstring newTitle);
|
||||||
|
|||||||
81
src/cascadia/WindowsTerminal/ErrorDialog.cpp
Normal file
81
src/cascadia/WindowsTerminal/ErrorDialog.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include <WerApi.h>
|
||||||
|
|
||||||
|
typedef wil::unique_any<HREPORT, decltype(&WerReportCloseHandle), WerReportCloseHandle> unique_wer_report;
|
||||||
|
|
||||||
|
struct ErrorDialogContext
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
std::wstring message;
|
||||||
|
HFONT font{ nullptr };
|
||||||
|
|
||||||
|
~ErrorDialogContext()
|
||||||
|
{
|
||||||
|
if (font)
|
||||||
|
{
|
||||||
|
DeleteObject(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static LRESULT CALLBACK ErrDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
// We've passed in the pointer to an error dialog context using DialogBoxParam
|
||||||
|
ErrorDialogContext* ctx{ reinterpret_cast<ErrorDialogContext*>(lParam) };
|
||||||
|
SetWindowLongPtrW(hDlg, DWLP_USER, reinterpret_cast<LONG_PTR>(ctx));
|
||||||
|
|
||||||
|
HWND editControl{ GetDlgItem(hDlg, IDC_ERRVALUE) };
|
||||||
|
const auto message{ std::format(L"HR 0x{0:08x}\r\n{1}", static_cast<unsigned int>(ctx->hr), ctx->message) };
|
||||||
|
SetWindowTextW(editControl, message.c_str());
|
||||||
|
|
||||||
|
HFONT& font{ ctx->font };
|
||||||
|
const auto fontHeight{ -MulDiv(10, GetDpiForWindow(hDlg), 72) };
|
||||||
|
font = CreateFontW(fontHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE | FIXED_PITCH, L"Cascadia Mono");
|
||||||
|
if (!font)
|
||||||
|
{
|
||||||
|
font = CreateFontW(fontHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE | FIXED_PITCH, L"Consolas");
|
||||||
|
}
|
||||||
|
// Context takes ownership of font and deletes it later
|
||||||
|
SendMessageW(editControl, WM_SETFONT, reinterpret_cast<WPARAM>(font), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
ErrorDialogContext* ctx{ reinterpret_cast<ErrorDialogContext*>(GetWindowLongPtrW(hDlg, DWLP_USER)) };
|
||||||
|
delete ctx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
case IDOK:
|
||||||
|
EndDialog(hDlg, TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayErrorDialogBlockingAndReport(const HRESULT hr, const std::wstring_view message)
|
||||||
|
{
|
||||||
|
auto ctx = new ErrorDialogContext{ hr, std::wstring{ message } };
|
||||||
|
DialogBoxParamW(nullptr, MAKEINTRESOURCEW(IDD_ERRDIALOG), nullptr, ErrDlgProc, reinterpret_cast<LPARAM>(ctx));
|
||||||
|
|
||||||
|
unique_wer_report errorReport;
|
||||||
|
WerReportCreate(L"AppCrash", WerReportApplicationCrash, nullptr, errorReport.put());
|
||||||
|
WerReportAddDump(errorReport.get(), GetCurrentProcess(), nullptr, WerDumpTypeMiniDump, nullptr, nullptr, 0);
|
||||||
|
WerReportSubmit(errorReport.get(), WerConsentNotAsked, 0, nullptr);
|
||||||
|
|
||||||
|
TerminateProcess(GetCurrentProcess(), 1);
|
||||||
|
}
|
||||||
2
src/cascadia/WindowsTerminal/ErrorDialog.h
Normal file
2
src/cascadia/WindowsTerminal/ErrorDialog.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
void DisplayErrorDialogBlockingAndReport(const HRESULT hr, const std::wstring_view message);
|
||||||
|
|
||||||
@@ -68,6 +68,23 @@ IDI_APPICON_HC_WHITE ICON "..\\..\\..\\res\\terminal\\imag
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Dialog
|
||||||
|
//
|
||||||
|
|
||||||
|
IDD_ERRDIALOG DIALOGEX 0, 0, 310, 177
|
||||||
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
|
CAPTION "Dialog"
|
||||||
|
FONT 10, "MS Shell Dlg", 400, 0, 0x1
|
||||||
|
BEGIN
|
||||||
|
DEFPUSHBUTTON "OK",IDOK,253,156,50,14
|
||||||
|
ICON 32513,IDC_STATIC,7,7,20,20
|
||||||
|
LTEXT "Windows Terminal has encountered an error and must exit.",IDC_STATIC,31,7,272,32
|
||||||
|
EDITTEXT IDC_ERRVALUE,7,31,296,121,ES_MULTILINE | ES_READONLY
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// String Table
|
// String Table
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<AdditionalIncludeDirectories>$(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>gdi32.lib;dwmapi.lib;Shcore.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wer.lib;gdi32.lib;dwmapi.lib;Shcore.lib;UxTheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
@@ -68,6 +68,7 @@
|
|||||||
<ClCompile Include="NotificationIcon.cpp" />
|
<ClCompile Include="NotificationIcon.cpp" />
|
||||||
<ClCompile Include="VirtualDesktopUtils.cpp" />
|
<ClCompile Include="VirtualDesktopUtils.cpp" />
|
||||||
<ClCompile Include="icon.cpp" />
|
<ClCompile Include="icon.cpp" />
|
||||||
|
<ClCompile Include="ErrorDialog.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="WindowsTerminal.rc" />
|
<ResourceCompile Include="WindowsTerminal.rc" />
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "../types/inc/User32Utils.hpp"
|
#include "../types/inc/User32Utils.hpp"
|
||||||
#include <WilErrorReporting.h>
|
#include <WilErrorReporting.h>
|
||||||
|
#include <winrt/Windows.ApplicationModel.Core.h>
|
||||||
|
#include "ErrorDialog.h"
|
||||||
|
|
||||||
using namespace winrt;
|
using namespace winrt;
|
||||||
using namespace winrt::Windows::UI;
|
using namespace winrt::Windows::UI;
|
||||||
@@ -127,25 +129,65 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
|||||||
// doing that, we can safely init as STA before any WinRT dispatches.
|
// doing that, we can safely init as STA before any WinRT dispatches.
|
||||||
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
winrt::init_apartment(winrt::apartment_type::single_threaded);
|
||||||
|
|
||||||
// Create the AppHost object, which will create both the window and the
|
auto unhandledErrorRevoker{
|
||||||
// Terminal App. This MUST BE constructed before the Xaml manager as TermApp
|
winrt::Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected(winrt::auto_revoke, [](auto&&...) {
|
||||||
// provides an implementation of Windows.UI.Xaml.Application.
|
winrt::com_ptr<IRestrictedErrorInfo> restrictedErrorInfo;
|
||||||
AppHost host;
|
if (SUCCEEDED(GetRestrictedErrorInfo(restrictedErrorInfo.put())) && restrictedErrorInfo)
|
||||||
if (!host.HasWindow())
|
{
|
||||||
|
wil::unique_bstr description, restrictedDescription, unused;
|
||||||
|
HRESULT hr;
|
||||||
|
if (SUCCEEDED(restrictedErrorInfo->GetErrorDetails(description.put(), &hr, restrictedDescription.put(), unused.put())))
|
||||||
|
{
|
||||||
|
DisplayErrorDialogBlockingAndReport(hr, restrictedDescription.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<AppHost> possiblyAppHost{ std::nullopt };
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// If we were told to not have a window, exit early. Make sure to use
|
// Create the AppHost object, which will create both the window and the
|
||||||
// ExitProcess to die here. If you try just `return 0`, then
|
// Terminal App. This MUST BE constructed before the Xaml manager as TermApp
|
||||||
// the XAML app host will crash during teardown. ExitProcess avoids
|
// provides an implementation of Windows.UI.Xaml.Application.
|
||||||
// that.
|
possiblyAppHost.emplace();
|
||||||
ExitProcess(0);
|
if (!possiblyAppHost->HasWindow())
|
||||||
|
{
|
||||||
|
// If we were told to not have a window, exit early. Make sure to use
|
||||||
|
// ExitProcess to die here. If you try just `return 0`, then
|
||||||
|
// the XAML app host will crash during teardown. ExitProcess avoids
|
||||||
|
// that.
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the xaml content. This must be called AFTER the
|
||||||
|
// WindowsXamlManager is initialized.
|
||||||
|
possiblyAppHost->Initialize();
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
const auto wideErrorMessage{ til::u8u16(e.what()) };
|
||||||
|
DisplayErrorDialogBlockingAndReport(E_FAIL, wideErrorMessage);
|
||||||
|
}
|
||||||
|
catch (const winrt::hresult_error& e)
|
||||||
|
{
|
||||||
|
DisplayErrorDialogBlockingAndReport(e.code(), e.message());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
DisplayErrorDialogBlockingAndReport(E_FAIL, L"LOL");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the xaml content. This must be called AFTER the
|
AppHost& host{ *possiblyAppHost };
|
||||||
// WindowsXamlManager is initialized.
|
|
||||||
host.Initialize();
|
|
||||||
|
|
||||||
MSG message;
|
MSG message;
|
||||||
|
|
||||||
|
if (!Feature_ReportErrorsThroughoutAppLifetime::IsEnabled())
|
||||||
|
{
|
||||||
|
// Disengage error reporting after XAML starts up.
|
||||||
|
unhandledErrorRevoker.revoke();
|
||||||
|
}
|
||||||
|
|
||||||
while (GetMessage(&message, nullptr, 0, 0))
|
while (GetMessage(&message, nullptr, 0, 0))
|
||||||
{
|
{
|
||||||
// GH#638 (Pressing F7 brings up both the history AND a caret browsing message)
|
// GH#638 (Pressing F7 brings up both the history AND a caret browsing message)
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
#define IDS_ARM_ARCHITECTURE 114
|
#define IDS_ARM_ARCHITECTURE 114
|
||||||
#define IDS_UNKNOWN_ARCHITECTURE 115
|
#define IDS_UNKNOWN_ARCHITECTURE 115
|
||||||
|
|
||||||
|
#define IDD_ERRDIALOG 129
|
||||||
|
#define IDC_ERRVALUE 1001
|
||||||
|
#define IDC_STATIC -1
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
|||||||
@@ -145,4 +145,14 @@
|
|||||||
<stage>AlwaysDisabled</stage>
|
<stage>AlwaysDisabled</stage>
|
||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
|
<feature>
|
||||||
|
<name>Feature_ReportErrorsThroughoutAppLifetime</name>
|
||||||
|
<description>Keep the error handler enabled throughout the lifetime of the application rather than only during startup</description>
|
||||||
|
<stage>AlwaysEnabled</stage>
|
||||||
|
<alwaysDisabledBrandingTokens>
|
||||||
|
<!-- For now, let's just let Release crash. Seeing a bunch of error dialogs might, puzzlingly, make us seem *less* reliable -->
|
||||||
|
<brandingToken>Release</brandingToken>
|
||||||
|
</alwaysDisabledBrandingTokens>
|
||||||
|
</feature>
|
||||||
|
|
||||||
</featureStaging>
|
</featureStaging>
|
||||||
|
|||||||
Reference in New Issue
Block a user