Какой правильный способ реализации расширения оболочки обработчика управляемого свойства?

StackOverflow https://stackoverflow.com/questions/3200245

Вопрос

Теперь, когда .NET CLR 4.0 поддерживает работу бок о бок (SXS), теперь теперь должна быть возможна запись оболочки Расширения в управляемом коде. Я попытался этому и успешно закодировал обработчик недвижимости Это реализует iPropertyStore, iinitializeWithstream и iPropertyStorectivity.

обработчик Работает нормально и называется, как ожидалось, при просмотре файлов через Explorer. Это также работает нормально в отображении Пользовательские свойства на панели предварительного просмотра и Панель свойств файла «Деталь».

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

Несколько Tidbits:

  1. Когда проводник вызывает iinitializeWithStream.initialize STGM-свойство установлено на STGM_SHARE_DENY_WRITE.
  2. и ни в точке делал исследователь вызов iPropertyStore.SetValue или iPropertyStore.comMit.
  3. Я вижу повторяющиеся звонки моему обработчику на разных потоках для тех же свойств файла.
  4. Так что мне нужно изменить (или установить в реестре), чтобы получить недвижимость для работы?

    <Сильное> Обновление:

    Благодаря Бену, у меня это работает. «Сложная часть» (по крайней мере для меня) было понимание того, что COM Interop никогда не будет позвонить утилизировать или доработать на своем собственности. Это оставило файлы, которые я обработал открытым до GC RAN.

    К счастью, «Протокол обработчика свойств» работает так, что когда IinitializeWithSream.initialize () вызывается для readValue () streammode, и когда он вызывается для setValue (), который steammode readwrite и commit () будет вызван в конце.

    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;
    }
    
    .

Это было полезно?

Решение

Да, вы должны добавить () поток, чтобы держать его открытым и поддерживать ссылку правильно.

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

Другие советы

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

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

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

-бен

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top