Gracefully handle unavailable TSF from SYSTEM account (#19635)

When run from SYSTEM account TSF seems to be unavailable. The only
missing step to handle that is check during initialization.

Not sure if fail after partial success in `Implementation::Initialize`
should also be gracefully handled.

Closes #19634

(cherry picked from commit 8bb831f628d3b8ddaf614c0a4d6f9b0b0533b5f0)
Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgiXm18
Service-Version: 1.23
This commit is contained in:
SEt 2025-12-10 01:46:27 +03:00 committed by Dustin L. Howett
parent b8f270a4f7
commit b4cf05a02c
3 changed files with 14 additions and 4 deletions

View File

@ -12,7 +12,11 @@ Handle Handle::Create()
{
Handle handle;
handle._impl = new Implementation();
handle._impl->Initialize();
if (!handle._impl->Initialize())
{
delete handle._impl;
handle._impl = nullptr;
}
return handle;
}

View File

@ -68,9 +68,14 @@ void Implementation::SetDefaultScopeAlphanumericHalfWidth(bool enable) noexcept
s_wantsAnsiInputScope.store(enable, std::memory_order_relaxed);
}
void Implementation::Initialize()
bool Implementation::Initialize()
{
_categoryMgr = wil::CoCreateInstance<ITfCategoryMgr>(CLSID_TF_CategoryMgr, CLSCTX_INPROC_SERVER);
_categoryMgr = wil::CoCreateInstanceNoThrow<ITfCategoryMgr>(CLSID_TF_CategoryMgr);
if (!_categoryMgr)
{
return false;
}
_displayAttributeMgr = wil::CoCreateInstance<ITfDisplayAttributeMgr>(CLSID_TF_DisplayAttributeMgr);
// There's no point in calling TF_GetThreadMgr. ITfThreadMgr is a per-thread singleton.
@ -89,6 +94,7 @@ void Implementation::Initialize()
THROW_IF_FAILED(_contextSource->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink*>(this), &_cookieTextEditSink));
THROW_IF_FAILED(_documentMgr->Push(_context.get()));
return true;
}
void Implementation::Uninitialize() noexcept

View File

@ -21,7 +21,7 @@ namespace Microsoft::Console::TSF
virtual ~Implementation() = default;
void Initialize();
bool Initialize();
void Uninitialize() noexcept;
HWND FindWindowOfActiveTSF() noexcept;
void AssociateFocus(IDataProvider* provider);