从MDItemRef确定本地驱动器

时间:2009-10-16 17:05:14

标签: objective-c usb-drive spotlight

当我收到Spotlight查询返回的MDItemRef项目列表(在obj-c中)时,我想知道是否有一种简单的方法可以确定它们是来自OS安装驱动器还是来自外部连接的USB驱动器。

基本前提是我想忽略本地驱动器中的任何内容,只关注外部USB驱动器上的文件。

谢谢!

3 个答案:

答案 0 :(得分:4)

Unasygerencía简单:

抓住项目的路径,看看它是否以“/ Volumes /”为前缀。如果是,则它在外部设备上。

示例:

MDItemRef myItem = ...;
NSString * itemPath = (NSString *)MDItemCopyAttribute(myItem, kMDItemPath);
if ([itemPath hasPrefix:@"/Volumes/"]) {
  NSLog(@"Found external item");
} else {
  NSLog(@"Found internal item");
}
[itemPath release];

答案 1 :(得分:4)

检查/ Volumes中的路径的问题是它还包括内部分区,例如/ Volumes / WINDOWS。此外,尽管很少见,但外部驱动器可以具有除/ Volumes

之外的安装点

更正确的方法是使用FSGetVolumeParms()获取包含有关该卷信息的GetVolParmsInfoBuffer结构,例如bIsEjectablebIsRemovablebIsOnInternalBus

您可以使用FSGetCatalogInfo()从FSRef获取FSVolumeRefNum:

FSCatalogInfo info = {0};
OSErr status = FSGetCatalogInfo(&fsRef, kFSCatInfoVolume, &info, nil, nil, nil);
if (status == noErr)
{
    _volumeRefNum = info.volume;
}

使用volumeRef,您可以获得音量参数:

FSGetVolumeParms(_volumeRefNum, &_params, sizeof(_params));

_params是GetVolParmsInfoBuffer结构,其信息如下:

- (BOOL) isEjectable
{
    return (_params.vMExtendedAttributes & (1 << bIsEjectable)) != 0;
}

- (BOOL) isRemovable
{
    return (_params.vMExtendedAttributes & (1 << bIsRemovable)) != 0;
}

- (BOOL) isAutoMounted
{
    return (_params.vMExtendedAttributes & (1 << bIsAutoMounted)) != 0;
}

- (BOOL) isExternal
{
    return (_params.vMExtendedAttributes & (1 << bIsOnExternalBus)) != 0;   
}

- (BOOL) isInternal
{
    return (_params.vMExtendedAttributes & (1 << bIsOnInternalBus)) != 0;   
}

答案 2 :(得分:0)

您是仅查看非启动驱动器还是外部驱动器(大多数情况下它们的含义相同,但在具有多个分区或多个内部驱动器的系统上(Mac Pro)可能会有所不同。) p>

如果您只需要非内部驱动器,则可以查看该路径是否以可移动驱动器安装点为前缀。

与Dave的代码相似:

MDItemRef myItem = ...;
NSString * itemPath = (NSString *)MDItemCopyAttribute(myItem, kMDItemPath);
NSArray * removableVolumes = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];
BOOL externalVolume = NO;

for (NSString *eachVolume in removableVolumes) {
    if ([itemPath hasPrefix: eachVolume]) {
        externalVolume = YES;
        break;
    }
}

上行 - 忽略内部驱动器(如果这就是你想要的) 下行 - 包括已安装的驱动器映像(在您的情况下,如果它们是Spotlight索引的,我想)。

这实际上需要一些工作 - 如果内部驱动器安装点与外部驱动器具有相同的前缀,它可能会返回误报 - 例如,内部驱动器安装在“/ Volumes / drive_2”和外部驱动器“/卷/驱动器”。