- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我被告知我可能无法访问通常用于将其 IFilter 加载到系统上的注册表或程序,因此我必须在应用程序中包含 IFilter dll 并直接从那里加载它们。我目前正在使用 CodeProject 的 C# IFilter 类,但是当涉及到 filterPersistClass、persistentHandlerClass 和 COM 时,它们仍然是我头上的一些事情,因此我对如何让它工作有点迷茫。
我已经完成了所有普通的事情,例如获取 dll、使用“扩展、DLL 路径”设置资源文件等等,但似乎无法掌握现在如何加载 IFilter DLL。也许我应该从头开始,但我想我会先寻求一些帮助。
编辑(部分解决方案)
好吧,我想出了如何在 FilterReader.cs 的 FilterReader 构造函数中使用下面的代码加载 query.dll,尽管我现在在加载 PDFFilter.dll 文件时遇到问题并收到以下错误:
无法在 DLL“C:\Program Files\Adobe\Adobe PDF iFilter 9 for 64-bit platforms\bin\PDFFilter.dll”中找到名为“LoadIFilter”的入口点
我认为我现在遇到的问题是 PDFFilter.dll 使用 STA 而 C# 应用程序是 MTA。
[DllImport("query.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int LoadIFilter(string pwcsPath, [MarshalAs(UnmanagedType.IUnknown)] ref object pUnkOuter, ref IFilter ppIUnk);
// --------------------------- constructor ----------------------------------
var isFilter = false;
object iUnknown = null;
LoadIFilter(fileName, ref iUnknown, ref _filter);
var persistFile = (_filter as IPersistFile);
if (persistFile != null)
{
persistFile.Load(fileName, 0);
IFILTER_FLAGS flags;
IFILTER_INIT iflags =
IFILTER_INIT.CANON_HYPHENS |
IFILTER_INIT.CANON_PARAGRAPHS |
IFILTER_INIT.CANON_SPACES |
IFILTER_INIT.APPLY_INDEX_ATTRIBUTES |
IFILTER_INIT.HARD_LINE_BREAKS |
IFILTER_INIT.FILTER_OWNED_VALUE_OK;
if (_filter.Init(iflags, 0, IntPtr.Zero, out flags) == IFilterReturnCode.S_OK)
isFilter = true;
}
if (_filter != null && isFilter) return;
if (_filter != null) Marshal.ReleaseComObject(_filter);
最佳答案
IFilter
对象没有什么神奇之处。它们位于标准 COM dll 中。最后,您只需要知道如何处理 pdf
文件的类的 clsid
即可。
query.dll
中的LoadIFilter
函数只是一个方便的辅助函数。它所做的一切你都可以自己做。
在注册表中有一种标准方法,其中文件扩展名(例如 .pdf
)被解析为 clsid
(例如 {E8978DA6- 047F-4E3D-9C78-CDBE46041603}
)
Note: You could also just skip to the end, and know that the clsid of Adobe's IFilter implementation is {E8978DA6-047F-4E3D-9C78-CDBE46041603}. But that's not guaranteed, so you need to crawl the registry.
将 .ext
解析为实现 IFilter
的对象的 clsid
的算法是:
GetIFilterClassIDForFileExtension(String extension)
arguments:
extension (String) e.g. ".pdf"
returns:
clsid (Guid) e.g.
//Get the Persistent Handler for this extension
//e.g.
// HKLM\Software\Classes\.pdf\PersistentHandler\(Default)
//returns
// "{F6594A6D-D57F-4EFD-B2C3-DCD9779E382E}"
persistentHandlerGuid = HKLM\Software\Classes\.pdf\PersistentHandler\(Default)
//Get the clsid associated with this persistent handler
//e.g.
// HKLM\Software\Classes\CLSID\{F6594A6D-D57F-4EFD-B2C3-DCD9779E382E}\PersistentAddinsRegistered\{89BCB740-6119-101A-BCB7-00DD010655AF}
//where the final guid is the interface identifier (IID) of IFilter
clsid = HKLM\persistentHandlerGuid\PersistentAddinsRegistered\{89BCB740-6119-101A-BCB7-00DD010655AF}
//e.g. returns "{E8978DA6-047F-4E3D-9C78-CDBE46041603}", the clsid of Adobe's PDF IFilter
return clsid
一旦您获得了相应对象的 clsid
,您就可以使用以下方法创建它:
Guid clsid = GetIFilterClassForFileExtension(".pdf")
IFilter filter = CreateComObject(clsid);
您现在拥有 query.dll
中的 LoadIFilter
函数的全部内容:
IFilter LoadIFilter(String filename)
{
String extension = ExtractFileExt(filename); //e.g. "foo.pdf" --> ".pdf"
Guid clsid = GetIFilterClassForFileExtension(extension);
return CreateComObject(clsid) as IFilter;
}
现在,所有这些仍然需要注册表,因为您仍然必须能够将 extension 解析为 clsid
。如果您已经知道 classid,则不需要注册表:
IFilter adobeIFilterForPdfs = CreateComObject("{E8978DA6-047F-4E3D-9C78-CDBE46041603}")
一切顺利。
重要的一点是您尝试调用的函数 LoadIFilter
不在 Adobe 的 dll 中(或任何其他公司提供的任何其他 IFilter dll,用于抓取任何其他文件类型)。 LoadIFilter
函数由 query.dll
导出,它只是我描述的上述步骤的辅助函数。
所有 IFilter
dll 都是 COM dll。记录的加载 COM dll 的方法是通过 CoCreateInstance
函数:
IUnknown CreateComObject(Guid ClassID)
{
IUnknown unk;
HRESULT hr = CoCreateInstance(ClassID, null, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, ref unk);
if (Failed(hr))
throw new Exception("Could not create instance: "+hr);
return unk;
}
我将留给您寻找从 C# 托管代码创建 COM 对象的正确方法。我忘记了。
Note: Any code released into public domain. No attribution required.
关于c# - 在没有注册表的情况下加载 IFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13024751/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 6 年前。
如何打开注册表 Win98/98SE/Me 运行中输入regedit.exe 无权限限制 Win2000/XP 1·开始>>运行.中输入regedit 2.运行中
目录 前言 使用简单工厂改进 使用注册表改进 参考文章 前言 在上一篇文章中我们提到了抽象工厂模式初版代码的一些缺点:①客户端违反开闭原则②提供方违反开
目录 工厂方法模式的瑕疵 注册表 工厂方法模式的瑕疵 在前一篇笔记中我们介绍了工厂方法模式,示例的类图如下: 考虑一种情况:现在要在程序运行时,根据外部资源
我在一个带有一个主节点和两个节点的 AWS 集群中安装了 mesosphere,分别称为主节点、节点 1 和节点 2。主节点是可见的,节点是私有(private)的。 我得到一个默认运行的马拉松实例和
我想用 PHP 制作一个注册表,将他们的用户名和密码注册到我的 SQL 数据库中。这是我所拥有的: 配置.php: 索引.php: Deltalus Account Regi
我正在尝试将我的软件添加到注册表中,我找到了一些我可以使用的代码,但不是完整的工作代码 C/C++ 对我来说是新的,无法自己创建它。但基本思想是:检查 reg key 是否已设置(如果未创建)。 我能
我尝试创建一个注册 php 代码,这样当我不在计算机旁时我就可以注册人们,但由于某种原因,它不会创建表,也不会创建文件夹,即使不存在。 输出是: ( ! ) Notice: Undefined var
我使用 HKLM\Software\etc\etc 来存储我的基本设置,这基本上是我的程序及其相关数据库的位置。 我现在遇到的问题是我已经创建了一个 Windows 服务并且需要读取这些位置。我无法将
我正在尝试将我的软件添加到注册表中,我找到了一些我可以使用的代码片段,但不是完整的工作代码 C/C++ 对我来说是新的,我无法自己创建它。但这里是基本的想法:如果没有创建它,请检查是否设置了注册键。
1、保存以下代码到:c:\windows\system32\vdm.vbs 复制代码 代码如下: Dim Args Set Args = WScript.Argum
不懂注册表、VBS、批处理不要紧,只要会学、会吸收别人的精华,会查找资料,|论坛|百度|GOOGLE|,然后能用好,就非常不错了 贴一些搜集的文字放到这吧。(绿色是标题, 蓝色的是原作者
(绿色是标题, 蓝色的是原作者,红色的部分就是需要修改的部分,根据你自己的实际情况修改) ======打开迅闪菜单的同时连接虚拟磁盘的VBS====== Set WshShell = WScrip
简单使用 复制代码 代码如下: <?php require_once("Zend/Loader.php"); Zend_Loader::loadCl
但并不是每次都打开同一个键值,在每多时候我们还是习惯于Windows 98那样每次打开都在根目录中。 通过修改注册表可以达到这样的效果。打开HKEY_CURRENT_USER\Software\M
何谓REG文件 REG文件实际上是一种注册表脚本文件,双击REG文件即可将其中的数据导入到注册表中。利用REG文件我们可以直接对注册表进行任何修改操作,它对注册表的操作可以不受注册表编辑器被禁用的
我应该将哪些数据和位置添加到 Windows 注册表中以正确创建文件关联? 我问这个问题主要是因为我多年前编写的一些旧应用程序使用 Visual Studio .NET 的 Windows Insta
我想阻止对默认 docker.io 注册表的访问。为了安全/IP 保护,我们需要阻止对公共(public) Docker 集线器的推/拉访问。 已有许多尝试将此作为配置选项,但所有 PR 都不断被拒绝
Lua 提供了一个 "registry" “任何 C 代码都可以使用它来存储它需要存储的任何 Lua 值”。正如 here 所说,线程“与原始线程共享其全局环境” .但是我找不到任何地方说它是否共享注
我的软件在 HKCU\Software\mysoftware 中存储了一些值,这从来都不是问题。但是,我现在还在 HKCU\Software\mysoftware\Licenses 中存储了一些值 -
我是一名优秀的程序员,十分优秀!