gpt4 book ai didi

c# - 在没有注册表的情况下加载 IFilter

转载 作者:行者123 更新时间:2023-11-30 21:03:07 27 4
gpt4 key购买 nike

所以我被告知我可能无法访问通常用于将其 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 不在 Adob​​e 的 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com