CLR не может создавать COM-объекты на основе.NET в UWP

Я создал библиотеку классов (.NET Framework 4.7.1), которая реализует текстовый сервис (ITfTextInputProcessorEx и т. д.) в ФБО, используя ComVisible приписывать. Я зарегистрировал это используя RegistrationServices и он может быть успешно распознан системой как метод ввода (IME) и может использоваться в большинстве приложений, кроме приложений UWP.

Использование в приложении Win32

В приложении Win32 (32-разрядная notepad.exe например), вот что происходит, когда я активирую свой Text Service на основе.NET (переключаясь на IME в языковой панели):

(Обведено YngPing.TSF.dll это сборка.NET, которая содержит реализацию COM-объекта. Загрузка, вызванная созданием COM-объекта, начинается с #56.)

По сути, после переключения на мой IME инфраструктура TSF (не код приложения, а выполняющийся в том же процессе) будет пытаться создать / запросить COM-объект моего Text Service, вызвав CoCreateObject, Потому что это не нативный COM-объект, mscoree.dll на самом деле "настоящая" COM DLL, которая находится в реестре. mscoree.dll сначала загружается, потом загружается mscoreei.dll, clr.dll и т.д., прежде чем, наконец, загрузить фактическую.NET DLL.

Использование в AppContainer (приложение UWP)

Теперь все это работает, как и ожидалось, в обычных настольных приложениях, но в приложении 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", а не устаревшие IME на основе API "Input Method Manager (IMM)".

1 ответ

Вы не должны использовать.net для написания IME. Мы разрешаем загружать в процесс только одну версию среды.net. Когда вы создаете IME с помощью.net, мы не можем гарантировать, что сможем загрузить правильную версию среды выполнения. Из-за этого IME может потерпеть неудачу. Вы всегда должны писать свои компоненты IME, используя неуправляемый C++.

Другие вопросы по тегам