wpf: delay-load UIAutomationCore because it's incomplete in RS1 (#15614)
UiaRaiseNotificationEvent is not present on Windows Server 2016, even though it is documented as being present. This also removes the cost of loading up UIAutomationCore from the critical path.
This commit is contained in:
parent
58e1380b8f
commit
99c18ce57e
|
@ -29,6 +29,7 @@ Dacl
|
|||
dataobject
|
||||
dcomp
|
||||
DERR
|
||||
delayimp
|
||||
dlldata
|
||||
DNE
|
||||
DONTADDTORECENT
|
||||
|
@ -167,6 +168,7 @@ roundf
|
|||
RSHIFT
|
||||
SACL
|
||||
schandle
|
||||
SEH
|
||||
semver
|
||||
serializer
|
||||
SETVERSION
|
||||
|
@ -214,6 +216,7 @@ UOI
|
|||
UPDATEINIFILE
|
||||
userenv
|
||||
USEROBJECTFLAGS
|
||||
Vcpp
|
||||
Viewbox
|
||||
virtualalloc
|
||||
vsnwprintf
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "HwndTerminalAutomationPeer.hpp"
|
||||
#include "../../types/UiaTracing.h"
|
||||
#include <UIAutomationCoreApi.h>
|
||||
#include <delayimp.h>
|
||||
|
||||
#pragma warning(suppress : 4471) // We don't control UIAutomationClient
|
||||
#include <UIAutomationClient.h>
|
||||
|
@ -13,6 +14,15 @@ using namespace Microsoft::Console::Types;
|
|||
|
||||
static constexpr wchar_t UNICODE_NEWLINE{ L'\n' };
|
||||
|
||||
static int CheckDelayedProcException(int exception) noexcept
|
||||
{
|
||||
if (exception == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND))
|
||||
{
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - creates a copy of the provided text with all of the control characters removed
|
||||
// Arguments:
|
||||
|
@ -123,6 +133,12 @@ void HwndTerminalAutomationPeer::SignalCursorChanged()
|
|||
|
||||
void HwndTerminalAutomationPeer::NotifyNewOutput(std::wstring_view newOutput)
|
||||
{
|
||||
if (_notificationsUnavailable) [[unlikely]]
|
||||
{
|
||||
// What if you tried to notify, but God said no
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to suppress any events (or event data)
|
||||
// that is just the keypress the user made
|
||||
auto sanitized{ Sanitize(newOutput) };
|
||||
|
@ -155,5 +171,19 @@ void HwndTerminalAutomationPeer::NotifyNewOutput(std::wstring_view newOutput)
|
|||
|
||||
const auto sanitizedBstr = wil::make_bstr_nothrow(sanitized.c_str());
|
||||
static auto activityId = wil::make_bstr_nothrow(L"TerminalTextOutput");
|
||||
LOG_IF_FAILED(UiaRaiseNotificationEvent(this, NotificationKind_ActionCompleted, NotificationProcessing_All, sanitizedBstr.get(), activityId.get()));
|
||||
_tryNotify(sanitizedBstr.get(), activityId.get());
|
||||
}
|
||||
|
||||
// This needs to be a separate function because it is using SEH try/except, which
|
||||
// is incompatible with C++ unwinding
|
||||
void HwndTerminalAutomationPeer::_tryNotify(BSTR string, BSTR activity)
|
||||
{
|
||||
__try
|
||||
{
|
||||
LOG_IF_FAILED(UiaRaiseNotificationEvent(this, NotificationKind_ActionCompleted, NotificationProcessing_All, string, activity));
|
||||
}
|
||||
__except (CheckDelayedProcException(GetExceptionCode()))
|
||||
{
|
||||
_notificationsUnavailable = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,5 +38,7 @@ public:
|
|||
void NotifyNewOutput(std::wstring_view newOutput) override;
|
||||
#pragma endregion
|
||||
private:
|
||||
void _tryNotify(BSTR string, BSTR activity);
|
||||
std::deque<wchar_t> _keyEvents;
|
||||
bool _notificationsUnavailable{};
|
||||
};
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
instead of APISet forwarders for easier Windows 7 compatibility. -->
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>Uiautomationcore.lib;onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>delayimp.lib;Uiautomationcore.lib;onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>uiautomationcore.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in New Issue