Как получить IPreviewHandler типа файла в последней версии .Net - PullRequest
1 голос
/ 19 апреля 2019

Недавно на работе я получил проект, который требует от меня предварительного просмотра файла определенного типа и отображения его на панели предварительного просмотра (аналогично панели предварительного просмотра в проводнике Windows).После 3 или 4 дней всестороннего изучения того, как этого добиться, я совершенно в тупике.

Сначала я попытался подписаться на этот пост Как получить IPreviewHandler для расширения файла? , но я никогда не мог заставить AssocQueryString возвращать что-либо, кроме какого-то действительно длинного случайного кода ошибки.После поиска другого решения я наткнулся на эту статью здесь https://www.brad -smith.info / blog / archives / 183 После ознакомления с его руководством и загрузки примера кода я смог создать предварительный просмотр для документов Word, но не для любого другого типа файла.Код, который сделал это возможным, состоял в следующем:

var comType = Type.GetTypeFromCLSID(CurrentPreviewHandler, true);
_mCurrentPreviewHandler = Activator.CreateInstance(comType);

if (_mCurrentPreviewHandler is IPreviewHandler handler)
{
   // bind the preview handler to the control's bounds and preview the content
   var r = ClientRectangle;
   handler.SetWindow(Handle, ref r);
   handler.DoPreview();
   return true;
}

После игры с отладчиком я обнаружил, что текстовые документы возвращают System .__ ComObject, тогда как тип файла, для которого я пытался создать предварительный просмотр, возвращалсяэкземпляр класса, который использовался для создания ShellExtension.Поэтому я вернулся в Интернет для дальнейших исследований и нашел этот пример CodeProject https://www.codeproject.com/Articles/25465/Using-Vista-Preview-Handlers-in-a-WPF-Application. Этот проект фактически создал предварительный просмотр для типа файла, который я искал!Я был очень взволнован, пока не заметил, что проект использовал Точный код, как указано выше , для генерации предварительного просмотра!Я был очень смущен, пока не заметил, что System.dll двух проектов были разных версий.Тот, который работал, был нацелен на .Net 3.5, а другой на .Net 4.6.1, что вызывает сожаление, потому что наш проект использует .Net 4.6.1.

Так что теперь, когда вы в курсе, вот мойвопрос.Есть ли способ получить предварительный просмотр файла в .Net 4.6.1 аналогично тому, как это делается в .Net 3.5?Кто-нибудь знает, что изменилось между двумя версиями?Или, может быть, есть совершенно другой способ сделать это, который работает лучше?Заранее спасибо!

PS Играя с отладчиком в проекте .Net 3.5, я заметил, что Type.GetTypeFromCLSID возвращал System .__ ComObject, который он также возвращал для документа word.Это как-то связано с этим?Кроме того, в то время как .Net 3.5 генерирует предварительный просмотр, он генерирует исключение System.Runtime.Serialization.SerializationException: «Попытка десериализации пустого потока».Я не знаю, полезно это или нет, но я решил включить это на всякий случай.

1 Ответ

0 голосов
/ 04 июня 2019

Примерно через полтора месяца попыток выяснить это, я наконец нашел решение ... вроде. Я обнаружил, что функции API C ++ все еще работают для генерации моего предварительного просмотра, поэтому я создал DLL C ++ для генерации моего предварительного просмотра. Я создал элемент border на стороне C # и установил его дочерний элемент как класс, унаследованный от HwndHost, так что граница получает дескриптор окна. Затем я передал дескриптор окна в свою C ++ dll и позволил dll позаботиться об остальной части работы по предварительному просмотру.

Я буду первым, кто признает, что это не идеальное решение, но на данный момент предварительный просмотр работает. Я отправил заявку на устранение неполадок при поддержке Microsoft, и если они придумают лучшее решение, чем я предоставлю это здесь. Также, если у кого-то возникнут вопросы о том, как это работает, оставьте комментарий, и я постараюсь добавить более подробное объяснение того, что я сделал.

...