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

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


person Alan Snyder    schedule 31.08.2017    source источник


Ответы (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;
}
person Alan Snyder    schedule 05.09.2017
comment
Было бы неплохо пометить ваш ответ как отвеченный (✔ рядом с ним) - person TT.; 31.10.2018