2012-10-23 105 views
2

因此我被告知我可能無法訪問註冊表或程序,通常它們將其IFilter加載到系統中,所以我必須將IFilter dll包含在應用程序中並直接加載它們從那裏。我目前使用CodeProject的C#IFilter類,但是當涉及到filterPersistClass,persistentHandlerClass和COM時,它們仍然是我頭上的一些東西,因此我有點失去了如何才能使它工作。在沒有註冊表的情況下加載IFilter

我已經完成了所有世俗的東西,如獲取DLL,設置一個資源文件與「擴展,DLL路徑」,但似乎無法得到如何現在加載IFilter DLL 。也許我應該從頭開始,但我認爲我會首先要求一些幫助。

EDIT(部分解決方案)

好吧,我想通了,如何加載query.dll在FilterReader.cs的FilterReader構造函數使用下面的代碼,雖然我有問題,現在加載PDFFilter.dll文件並且出現以下錯誤:

無法在DLL'C:\ Program Files \ Adob​​e \ Adob​​e PDF iFilter 9 for 64-bit platforms \ bin \ PDFFilter.dll'中找到名爲'LoadIFilter'的入口點。

問題I th我現在卡在的墨水是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); 
+0

那麼,停止你在做什麼,因爲它沒有註冊的過濾器不會工作。索引器使用註冊表來查找過濾器。 –

回答

3

對於IFilter對象沒有什麼神奇的。他們被安置在標準COM dlls中。最後,所有你需要知道如何處理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到一個企業的clsid實現IFilter目標是:

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); 

您現在有LoadIFilter功能整膽從query.dll

IFilter LoadIFilter(String filename) 
{ 
    String extension = ExtractFileExt(filename); //e.g. "foo.pdf" --> ".pdf" 
    Guid clsid = GetIFilterClassForFileExtension(extension); 
    return CreateComObject(clsid) as IFilter; 
} 

現在,這一切,仍然需要對註冊表,因爲你還是要能夠解決的擴展成a 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.

相關問題