Я создал библиотеку классов (.NET Framework 4.7.1), которая реализует текстовую службу (ITfTextInputProcessorEx
и т. Д.) В TSF с использованием атрибута ComVisible
.Я зарегистрировал его, используя RegistrationServices
, и он может быть успешно распознан системой как метод ввода (IME) и может использоваться в большинстве приложений, кроме приложений UWP.
Использование в приложении Win32
В приложении Win32 (например, 32-разрядном notepad.exe
) происходит следующее, когда я активирую свой TextService на основе .NET (переключаясь на IME в языковой панели):
(Обведенный YngPing.TSF.dll
- это сборка .NET, которая содержит реализацию COM-объекта. Загрузка, вызванная созданием COM-объекта, начинается с # 56.)
По сути, после переключения на мой IME инфраструктура TSF (не код приложения, а выполняющийся в том же процессе) будет пытаться создать / запросить COM-объект моего TextService, вызвав CoCreateObject
.Поскольку это не собственный COM-объект, mscoree.dll
на самом деле является «настоящей» COM-DLL, которая находится в реестре.mscoree.dll
сначала загружается, затем загружается mscoreei.dll
, clr.dll
и т. Д., Прежде чем окончательно загрузить фактическую .NET DLL.
Использование в AppContainer (приложение UWP)
Теперь все это работает, как и ожидалось, в обычных приложениях Desktop, но в приложении UWP тот же процесс остановится после того, как mscoree.dll
и mscoreei.dll
будутзагружен (т.е. clr.dll
и моя сборка .NET не загружены).Стек вызовов выглядит следующим образом:
( Тестируемое здесь приложение UWP - это просто пустое приложение с текстовым полем. Все эти загрузки COM все инициируются ФБО. )
Еще одно наблюдение: после завершения вызовов mscoree.dll
один из указателей внутри combase.dll
устанавливается на E_NOTIMPL
.
В том же приложении UWP библиотеки DLL других IME сторонних производителей (например, https://github.com/rime/weasel, написанные на C ++) могут загружаться и использоваться без проблем.Мне еще предстоит протестировать официальный пример, https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/IME, но я вполне уверен, что он тоже будет работать.
У меня есть приблизительное представление о том, что происходит, но мне не хватаетопыт более глубокого погружения в основную причину: что происходит для COM-объектов на основе .NET, CLR загружается первым, когда запрашивается COM-объект;но в этом случае для UWP CLR почему-то не удалось загрузить, и впоследствии COM-объект не может быть инициирован.
Я также использовал Fusion Log (с режимом погружения для UWP), но не видел связанных сообщений.Я думаю, это потому, что даже clr.dll
не загружается в моем случае.
Может кто-нибудь предложить какие-то идеи относительно того, как решить эту проблему?Спасибо!
Обновление: когда я говорю «IME» в этом посте, я имею в виду «текстовую службу, использующую API-интерфейс Text Service Framework», а не устаревшую API-интерфейс «Input Method Manager (IMM)».IME на основе.