注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

_

_

 
 
 

日志

 
 

adobemicrosoftdllfilter文档office Adobe PDF 过滤器在关闭时使应用程序崩溃  

2014-07-16 15:12:02|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Ifilter
分类: 文件格式 2012-09-20 12:36 184人阅读 评论(0) 收藏 举报
adobemicrosoftdllfilter文档office

什么是IFilter?
IFilter接口由微软设计,便于在索引服务中使用。主要为了从文件抽取文本,从而使索引服务能够索引及搜索。一些版本的windows本身实现了若干Office文件的IFilter接口,也有一些用于其他文件类型---比较流行的Adobe PDF 过滤器---免费和商用的过滤器。IFilter接口主要用于抽取文件的重要部分,像Office文档、PDF文档等非文本文件,但也用于HTML、XML等文本文件。虽然IFilter接口通常用作从文档抽取文本,但是它广泛应用于搜索引擎。Windows桌面搜索就使用过滤器索引文件。

另一些新东西
已经有许多关于如何在.NET中实现IFilter接口的文章和信息,或许你会问为什么还要写这篇文章?那些文章提到的实现方法存在一些问题,这促使我寻求一种不同的方法使用、载入过滤器。我在开发的新产品中使用,直到现在运行良好,故而决定和你分享---是的,和你!

实现概要
下面是我和其他人发现的概要,我接下来会详细讨论:
1.从大文件抽取文本
2.COM线程的问题
3.Adobe PDF 过滤器在关闭时使应用程序崩溃

从大文件抽取文本

在我找到的所有使用IFilter抽取文本并返回一个字符串的C#示例代码中都提供一个方法。通常,像如下写法:
public static string getTextFromFile(string path)
现在,或许可以满足一些用户,但是对于专门的索引,我觉得它不是最好的办法。一些文档非常大---30M的PDF或word文档并不罕见---一下抽取整个文本或许对垃圾回收器产生负面影响,既然这些对象将被存储在.NET的“大的对象堆”里。

COM线程的问题

过滤器本质上是COM 对象,所以他们带有一些让我们又爱又恨的COM线程模型问题。长话短说,一些过滤器标有STA(Adobe PDF filter),一些标有MTA(Microsoft XML filter),或两者皆有(Microsoft Office Filter)。这意味着MTA过滤器不能载入标有[STAThread]的C#线程,反之亦然。有人建议手动更改有问题的过滤器,但在产品安装时仍然存在一些你想不到的问题,由于你不清楚客户电脑上安装过哪种过滤器而带来的不可靠性。我们主要需要一种载入、使用过滤器的方法,不管是谁的线程模型。

Adobe PDF 过滤器在关闭时使应用程序崩溃

关于Adobe PDF过滤器的报道相当多。研究了一段时间,我认为我找到了问题所在。Adobe忘记(或许没有)了从他们的PDFFILT.dll导出DLLCanUnloadNow函数。既然一个过滤器实现了一个COM对象,它就应该导出这个函数以通知COM什么时候它能卸载这个库。这可能就是C#应用程序中问题的原因------这个dll从来没有被卸载,当真正去卸载时,为时已晚。

在我以前的应用程序版本中,我通过明确卸载PDFFILT.dll库以绕过该问题。现在,不必这样了。

我如何解决?

实现一个FilterReader
我决定克服困难,实现一个派生自FilterReader的类TextReader。这解决了问题1,因为我们不必一下子抽取整个文本。相反,你仅仅使用reader一次读取一个缓冲。如果你想得到作为一个字符串的整个文本,可以用ReadToEnd()方法。

绕过COM
要得到一个IFilter实例,你应调用LoadIFilter API,并传给他一个文件名。实际上,LoadIFilter最终调用CoCreateInstance()实例化过滤器,从而符合COM规则。为了避免线程问题,我决定绕过COM,实例化我自己的过滤器COM类。以下是介绍和设想:
1.我需要找到实现了某种特定文件类型的正确的COM类。
2.我需要动态载入实现了COM的dll,调用从dll导出的DllGetClassObject函数
3.我不想重新实现COM架构,因此为了卸载没用的COM dll,我决定在整个应用程序生命期内保留这些dll,仅在应用程序结束时卸载它们.注意,这解决了问题3,既然我们手动卸载PDFFILT.dll.
4.一个IFilter不应该被多个线程操控,既然他不再受COM保护.
5.我假定,当与COM无关时,一个STA过滤器在被MTA线程调用时,工作正常.直到现在,我没有碰到任何问题.如果你用此法遇到问题,请告知我.

总结
我们通过实现一个FilterReader解决问题1
通过绕过COM解决问题2和3

代码使用
这非常简单:
通过传递一个你要抽取文本的文件,实例化一个FilterReader,然后调用之,和任何TextReader的派生类一样。
TextReader reader=new FilterReader(fileName);
using (reader)
{
  textBox1.Text=reader.ReadToEnd();
}

以下部分略去

原文地址:http://www.codeproject.com/csharp/IFilter.asp

  评论这张
 
阅读(263)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017