Конфликты версий
Конфликт версий может возникнуть из-за среды выполнения, которая не поддерживает загрузку нескольких версий среды выполнения в одном процессе. Версии среды CLR до версии 4.0 попадают в эту категорию. Если загрузка одной версии среды выполнения препятствует загрузке других версий той же среды выполнения, это может создать конфликт, если ведущее приложение или другое внутрипроцессное расширение использует конфликтующую версию. В случае конфликта версии с другим расширением внутри процесса, конфликт может быть трудно воспроизвести, потому что сбой требует правильных конфликтующих расширений, а режим сбоя зависит от порядка, в котором загружаются конфликтующие расширения.
Рассмотрим внутрипроцессное расширение, написанное с использованием версии CLR до версии 4.0. Каждое приложение на компьютере, которое использует диалоговое окно открытия файла, потенциально может иметь управляемый код диалогового окна и его сопутствующую зависимость CLR, загруженную в процесс приложения. Приложение или расширение, которое первым загружает версию CLR до 4.0 в процесс приложения, ограничивает, какие версии CLR могут впоследствии использоваться этим процессом. Если управляемое приложение с диалоговым окном «Открыть» построено на конфликтующей версии среды CLR, расширение может работать некорректно и вызывать сбои в приложении. И наоборот, если расширение загружается первым в процессе, а конфликтующая версия управляемого кода пытается запустить после этого (возможно, управляемое приложение или запущенное приложение загружает среду CLR по запросу), операция завершается ошибкой. Пользователю кажется, что некоторые функции приложения случайным образом перестают работать или приложение таинственным образом вылетает.
Обратите внимание, что версии CLR, равные или более поздние, чем версия 4.0, обычно не подвержены проблеме управления версиями, потому что они предназначены для сосуществования друг с другом и с большинством версий CLR до 4.0 (за исключением версии 1.0, которая не может сосуществуют с другими версиями). Однако могут возникнуть проблемы, отличные от конфликтов версий, которые обсуждаются в оставшейся части этого раздела.
Проблемы с производительностью
Проблемы с производительностью могут возникать в среде выполнения, которая значительно снижает производительность при загрузке в процесс. Ухудшение производительности может выражаться в использовании памяти, использовании ЦП, затраченном времени или даже потреблении адресного пространства. CLR, JavaScript / ECMAScript и Java известны как среды выполнения с высокой степенью воздействия. Поскольку внутрипроцессные расширения могут быть загружены во многие процессы, и часто это делается в моменты, когда важна производительность (например, при подготовке меню для отображения пользователю), время выполнения с высокой отдачей может негативно повлиять на общую скорость реагирования.
Среда выполнения с высокой степенью воздействия, которая потребляет значительные ресурсы, может вызвать сбой в хост-процессе или другом внутрипроцессном расширении. Например, высокоэффективная среда выполнения, которая потребляет сотни мегабайт адресного пространства для своей кучи, может привести к тому, что ведущее приложение не сможет загрузить большой набор данных. Кроме того, поскольку внутрипроцессные расширения могут быть загружены в несколько процессов, высокое потребление ресурсов в одном расширении может быстро перерасти в высокое потребление ресурсов во всей системе.
Если среда выполнения остается загруженной или иным образом продолжает потреблять ресурсы, даже если расширение, которое использует эту среду выполнения, выгружено, то эта среда выполнения не подходит для использования в расширении.
Проблемы, связанные с .NET Framework
В следующих разделах обсуждаются примеры проблем, обнаруженных при использовании управляемого кода для расширений. Это не полный список всех возможных проблем, с которыми вы можете столкнуться. Обсуждаемые здесь проблемы являются одновременно причинами, по которым управляемый код не поддерживается в расширениях, и моментами, которые следует учитывать при оценке использования других сред выполнения.
Повторный вход
Когда среда CLR блокирует поток однопоточного подразделения (STA), например, из-за Monitor.Enter, WaitHandle.WaitOne или оператора конкурирующей блокировки, среда CLR в в своей стандартной конфигурации входит во вложенный цикл сообщений во время ожидания. Многим методам расширения запрещено обрабатывать сообщения, и этот непредсказуемый и неожиданный повторный вход может привести к аномальному поведению, которое трудно воспроизвести и диагностировать.
Многопоточная квартира. CLR создает вызываемые оболочки времени выполнения для объектов модели компонентных объектов (COM). Эти же вызываемые оболочки среды выполнения уничтожаются позже финализатором CLR, который является частью многопоточного подразделения (MTA). Для перемещения прокси-сервера с STA на MTA требуется маршалинг, но не все интерфейсы, используемые расширениями, можно маршалировать.
Недетерминированное время жизни объекта
CLR имеет более слабые гарантии времени жизни объекта, чем собственный код. Многие расширения предъявляют требования к количеству ссылок на объекты и интерфейсы, и модель сборки мусора, используемая CLR, не может удовлетворить эти требования.
- If a CLR object obtains a reference to a COM object, the COM object reference held by the Runtime Callable Wrapper is not released until the Runtime Callable Wrapper is garbage-collected. Nondeterministic release behavior can conflict with some interface contracts. For example, the IPersistPropertyBag::Load method requires that no reference to the property bag be retained by the object when the Load method returns.
- Если ссылка на объект CLR возвращается в машинный код, Runtime Callable Wrapper отказывается от своей ссылки на объект CLR, когда выполняется последний вызов Runtime Callable Wrapper для Release, но базовый объект CLR не завершается, пока он не будет собран сборщиком мусора. Недетерминированная финализация может конфликтовать с некоторыми интерфейсными контрактами. Например, обработчики эскизов должны немедленно освободить все ресурсы, когда их счетчик ссылок упадет до нуля.
Допустимое использование управляемого кода и других сред выполнения
Допускается использование управляемого кода и других сред выполнения для реализации внепроцессных расширений. Примеры внепроцессных расширений оболочки включают следующее:
- Предварительный просмотр обработчиков
- Действия на основе командной строки, например, зарегистрированные в подразделах shell \ verb \ command.
- COM-объекты, реализованные на локальном сервере, для точек расширения оболочки, которые позволяют активацию вне процесса.
Некоторые расширения могут быть реализованы как внутрипроцессные, так и внепроцессные расширения. Вы можете реализовать эти расширения как внепроцессные расширения, если они не соответствуют этим требованиям для внутрипроцессных расширений. В следующем списке показаны примеры расширений, которые могут быть реализованы как внутрипроцессные, так и внепроцессные расширения:
- IExecuteCommand, связанный с записью DelegateExecute, зарегистрированной в подразделе оболочки \ verb \ command.
- IDropTarget, связанный с CLSID, зарегистрированным в подразделе оболочки \ verb \ DropTarget.
- IExplorerCommandState, связанный с записью CommandStateHandler, зарегистрированной в подразделе shell \ verb.
SharpShell упрощает создание расширений оболочки Windows с помощью .NET Framework.
Исходный код размещен на https://github.com/dwmkerr/sharpshell - вы можете задавать вопросы и запрос функции здесь или там. Поддерживаемые расширения
Вы можете использовать SharpShell для создания любого из следующих расширений:
- Контекстные меню оболочки
- Обработчики значков
- Обработчики информационных советов
- Обработчики падения
- Предварительный просмотр обработчиков
- Обработчики наложения значков
- Обработчики миниатюр
- Расширения страницы свойств
Проекты, в которых используется SharpShell
1. Контекстное меню Trello
2. REAL Shuffle Player 2.0
Серии статей на CodeProject
person
Ehsan Mohammadi
schedule
09.02.2014