Может ли один импортер Spotlight позвонить другому?

У меня есть приложение MacOS, которое хранит текст в виде HTML-файла внутри пакета (связки каталогов). Системный импортер Rich Text уже знает, как извлечь текст из файлов HTML. Есть ли способ написать средство импорта для моего приложения, которое вызывает средство импорта Rich Text для файла HTML? Из стандартного кода Spotlight Importer я вижу, что он вызывается как плагин COM, но неясно, как вызвать его из моего импортера.

1 ответ

Я понял, как это сделать:

#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <CoreFoundation/CFPlugInCom.h>

Boolean GetMetadataForFile(void *thisInterface,
                           CFMutableDictionaryRef attributes,
                           CFStringRef contentTypeUTI,
                           CFStringRef pathToFile);

Boolean getMetadataFromRichTextFile(CFMutableDictionaryRef attributes,
                                    CFStringRef contentTypeUTI,
                                    CFStringRef pathToFile)
{
    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/System/Library/Spotlight/RichText.mdimporter"), kCFURLPOSIXPathStyle, TRUE);
    CFPlugInRef plugin = CFPlugInCreate(NULL, url);

    Boolean result = FALSE;
    if (!plugin) {
        printf("Unable to load RichText importer\n");
    } else {
        CFArrayRef factories = CFPlugInFindFactoriesForPlugInTypeInPlugIn(kMDImporterTypeID, plugin);
        if ((factories != NULL) && (CFArrayGetCount(factories) > 0)) {
            CFUUIDRef factoryID = CFArrayGetValueAtIndex(factories, 0);
            IUnknownVTbl **iunknown = CFPlugInInstanceCreate(NULL, factoryID, kMDImporterTypeID);
            if (iunknown) {
                MDImporterInterfaceStruct **interface = NULL;
                (*iunknown)->QueryInterface(iunknown, CFUUIDGetUUIDBytes(kMDImporterInterfaceID), (LPVOID *)(&interface));
                (*iunknown)->Release(iunknown);
                if (interface) {
                    (*interface)->ImporterImportData(interface, attributes, contentTypeUTI, pathToFile);
                    (*interface)->Release(interface);
                    result = TRUE;
                } else {
                    printf("Failed to get MDImporter interface.\n");
                }
            } else {
                printf("Failed to create RichText importer instance.\n");
            }
        } else {
            printf("Could not find RichText importer factory.\n");
        }

        CFRelease(plugin);
    }
    return result;
}

Boolean GetMetadataForFile(void *thisInterface,
                           CFMutableDictionaryRef attributes,
                           CFStringRef contentTypeUTI,
                           CFStringRef pathToFile)
{
    Boolean result = FALSE;
    @autoreleasepool {
        CFStringRef path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/index.html"), pathToFile);
        result = getMetadataFromRichTextFile(attributes, kUTTypeHTML, path);
    }
    return result;
}
Другие вопросы по тегам