Что корректный путь состоит в том, чтобы реализовать Управляемый Обработчик Свойств Расширение Shell?

Теперь, когда.NET CLR 4.0 поддерживает рядом (SxS) операцию, должно теперь быть возможно записать расширения оболочки в управляемом коде. Я делал попытку этого и успешно кодировал Обработчик Свойств, который реализует IPropertyStore, IInitializeWithStream и IPropertyStoreCapabilities.

Обработчик хорошо работает и назван как ожидалось при просмотре файлов с помощью проводника. Это также хорошо работает в отображении пользовательских свойств в панели предварительного просмотра, и свойства файла "детализируют" панель.

Однако, когда я пытаюсь отредактировать свойство в панели предварительного просмотра, и затем нажимать "Save" я получаю "Файл Используемая" ошибка при высказывании, что файл открыт в Windows Explorer.

Несколько лакомых кусочков:

  1. Когда проводник называет IInitializeWithStream. Инициализируйте свойство STGM, установлен на STGM_SHARE_DENY_WRITE.
  2. И ни в каком смысле сделал вызов проводника IPropertyStore. SetValue или IPropertyStore. Фиксация.
  3. Я вижу повторенные вызовы к своему обработчику на различных потоках для тех же свойств файла.

Таким образом, что я должен изменить (или установить в реестре) для получения свойства сохраняют для работы?

Обновление:

Благодаря Ben у меня есть он работа. "Трудная часть" (по крайней мере, для меня) понимала, что взаимодействующий с COM никогда не будет звонить, Располагают или Завершают на моем PropertyHandler. Это оставляло файлы, которые я обработал открытый, пока GC не работал.

К счастью, "протокол обработчика свойств" работает таким образом что когда IInitializeWithSream. Инициализируйте (), назван для ReadValue (), streamMode является ReadOnly, и когда это называют для SetValue (), streamMode является ReadWrite, и Фиксацию () назовут в конце.

int IInitializeWithStream.Initialize( IStream stream, uint grfMode )
{
    _stream = stream;
    _streamMode = (Stgm)grfMode;

    Load();

    // We release here cause if this is a read operation we won't get called back, 
    // and our finializer isn't called. 
    if ( ( _streamMode & Stgm.ReadWrite ) != Stgm.ReadWrite )
    {
        Marshal.ReleaseComObject( _stream );
        _stream = null;
    }
    return HResult.S_OK;
}

int IPropertyStore.Commit()
{
    bool result = false;

    if ( _stream != null )
    {
        result = WriteStream( _stream );
        Marshal.ReleaseComObject( _stream );
        _stream = null;
    }

    return result ? HResult.S_OK : HResult.E_FAIL;
}
5
задан David Lynch 14 July 2010 в 16:22
поделиться

2 ответа

Да, вы должны использовать AddRef () для потока, чтобы он оставался открытым и чтобы ссылка оставалась активной.

Обратите внимание, что индексатор также будет использовать обработчик вашего свойства для открытия файла. Таким образом, если вы просочите объект потока, файл останется открытым. Вы можете использовать процедуру sysinternals, чтобы узнать, какой процесс открыл файл, или procmon, чтобы узнать, какие вызовы и параметры он использовал.

3
ответ дан 15 December 2019 в 00:48
поделиться

Проводник пытается убедиться, что он не мешает другим приложениям, которые могут открыть файл. Может ли файл законно использоваться другим приложением? Открыт ли обработчик предварительного просмотра?

Иногда мы видим обработчики свойств, которые держат свои потоки открытыми дольше, чем необходимо (или файловые обработчики, открывающие файл с ограниченными разрешениями). Можете ли вы проверить, своевременно ли вы выпускаете поток?

Наконец, я не думаю, что это связано с вашей непосредственной проблемой, но использование расширений оболочки .NET не поддерживается. Мы рекомендуем не включать это ни в один продукт.

-Бен

1
ответ дан 15 December 2019 в 00:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: