如何在最新版本的.Net中获取文件类型的IPreviewHandler

时间:2019-04-19 17:44:44

标签: c# .net comobject ipreviewhandler

最近在工作中,我收到了一个项目,该项目要求我获得特定文件类型的预览并将其显示在预览窗格中(类似于Windows文件资源管理器中的预览窗格)。经过3或4天的广泛研究,以实现这一目标,我完全陷入了困境。

起初,我尝试关注这篇文章How to get the IPreviewHandler for a file extension?,但是除了一些很长的随机错误代码之外,我无法让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;
}

在调试器中玩耍之后,我发现Word文档返回了System .__ ComObject,而我试图为其生成预览的文件类型正在返回用于创建ShellExtension的类的实例。因此,我回到了Internet进行更多研究,并找到了此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中的预览类似?有人知道这两个版本之间有什么变化吗?或者,也许有一种完全不同的方法可以更好地起作用?提前致谢!

P.S。在.Net 3.5项目中使用调试器时,我注意到Type.GetTypeFromCLSID返回的是System .__ ComObject,这也是Word文档返回的内容。这和它有关吗?同样,当.Net 3.5确实生成预览时,它会引发此异常System.Runtime.Serialization.SerializationException:“试图对空流进行反序列化”。我不知道这是否有帮助,但我认为我会以防万一。

1 个答案:

答案 0 :(得分:0)

大约一个半月后,我终于找到了解决方案……。我发现C ++ API函数仍可用于生成预览,因此我创建了一个C ++ dll用于生成预览。我在事物的C#端创建了一个border元素,并将其子元素设置为继承自HwndHost的类,以便该Border获得窗口句柄。然后,我将窗口句柄传递到我的C ++ dll中,让该dll负责绘制预览的其余工作。

我将是第一个承认这不是一个完美的解决方案的人,但是现在预览可以使用了。我在Microsoft的支持下提交了故障单,如果他们提出了比我在此处提供的解决方案更好的解决方案。另外,如果有人对此工作方式有任何疑问,请留下评论,我将尝试为我的工作添加更详细的解释。