Как получить IPreviewHandler типа файла в последней версии.Net
Недавно на работе я получил проект, который требует от меня предварительного просмотра файла определенного типа и отображения его на панели предварительного просмотра (аналогично панели предварительного просмотра в проводнике Windows). После 3 или 4 дней всестороннего изучения того, как этого добиться, я совершенно в тупике.
Сначала я пытался следовать этому посту Как получить IPreviewHandler для расширения файла? но я никогда не мог заставить AssocQueryString возвращать что-либо, кроме действительно длинного кода случайной ошибки. После поиска другого решения я наткнулся на эту статью здесь https://www.brad-smith.info/blog/archives/183 После изучения его учебника и загрузки примера кода я смог создать предварительный просмотр для текстовых документов, но не для любого другого типа файла. Код, который сделал это возможным, был вот такими строками
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: "Попытка десериализации пустого потока". Я не знаю, полезно это или нет, но я решил включить это на всякий случай.
0 ответов
Примерно через полтора месяца попыток выяснить это, я наконец нашел решение... вроде. Я обнаружил, что функции API C++ все еще работают для генерации моего предварительного просмотра, поэтому я создал DLL C++ для генерации моего предварительного просмотра. Я создал элемент border на стороне C# и установил его дочерний элемент как класс, унаследованный от HwndHost, так что граница получает дескриптор окна. Затем я передал дескриптор окна в свою C++ dll и позволил dll позаботиться об остальной части работы по предварительному просмотру.
Я буду первым, кто признает, что это не идеальное решение, но оно пока работает. Я отправил заявку на устранение неполадок при поддержке Microsoft, и если они придумают лучшее решение, чем я предоставлю это здесь. Также, если у кого-то возникнут вопросы о том, как это работает, оставьте комментарий, и я постараюсь добавить более подробное объяснение того, что я сделал.