5

我想获取在 OS X 下使用 Cocoa/Objective-C 无法安装/可弹出的驱动器列表。

我希望 NSWorkspace getFileSystemInfoForPath::::: 能帮助我:

NSArray* listOfMedia = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths];
NSLog(@"%@", listOfMedia);

for (NSString* volumePath in listOfMedia)
{
    BOOL isRemovable = NO;
    BOOL isWritable  = NO;
    BOOL isUnmountable = NO;
    NSString* description = [NSString string];
    NSString* type = [NSString string];

    BOOL result = [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:volumePath 
                                                             isRemovable:&isRemovable 
                                                              isWritable:&isWritable 
                                                              isUnmountable:&isUnmountable 
                                                                description:&description
                                                                       type:&type];
    NSLog(@"Result:%i Volume: %@, Removable:%i, W:%i, Unmountable:%i, Desc:%@, type:%@", result, volumePath, isRemovable, isWritable, isUnmountable, description, type);
}

输出:

...
Result:1 Volume: /Volumes/LR Photos, Removable:0, W:1, Unmountable:0, Desc:hfs, type:hfs
...

“LR Photos”是一个外部驱动器(通过 Thunderbolt 连接),应该是可移动和/或不可安装的(或者,至少我认为它应该是)。:)

我应该以不同的方式解决这个问题吗?

提前致谢!

4

3 回答 3

6

您可以使用diskArbitration 框架

#import <DiskArbitration/DiskArbitration.h>
   +(NSMutableArray *)getListOfEjectableMedia
{
    NSArray *mountedRemovableMedia = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:nil options:NSVolumeEnumerationSkipHiddenVolumes];
    NSMutableArray *result = [NSMutableArray array];
    for(NSURL *volURL in mountedRemovableMedia)
    {
        int                 err = 0;
        DADiskRef           disk;
        DASessionRef        session;
        CFDictionaryRef     descDict;
        session = DASessionCreate(NULL);
        if (session == NULL) {
            err = EINVAL;
        }
        if (err == 0) {
            disk = DADiskCreateFromVolumePath(NULL,session,(CFURLRef)volURL);
            if (session == NULL) {
                err = EINVAL;
            }
        }
        if (err == 0) {
            descDict = DADiskCopyDescription(disk);
            if (descDict == NULL) {
                err = EINVAL;
            }
        }
        if (err == 0) {
            CFTypeRef mediaEjectableKey = CFDictionaryGetValue(descDict,kDADiskDescriptionMediaEjectableKey);
            CFTypeRef deviceProtocolName = CFDictionaryGetValue(descDict,kDADiskDescriptionDeviceProtocolKey);
            if (mediaEjectableKey != NULL)
            {
                BOOL op = CFEqual(mediaEjectableKey, CFSTR("0")) || CFEqual(deviceProtocolName, CFSTR("USB"));
                if (op) {
                    [result addObject:volURL];
                }
            }
        }
        if (descDict != NULL) {
            CFRelease(descDict);
        }
        if (disk != NULL) {
            CFRelease(disk);
        }
        if (session != NULL) {
            CFRelease(session);
        }
    }
    return result;
}
于 2013-10-23T10:05:42.027 回答
3

不幸getFileSystemInfoForPath:的是,这并不是真正的正确方法。可移动意味着该卷位于 CD 或 DVD 等可移动媒体上。在实践中,unmountable 似乎给出了与可移除相同的结果。例如,请参阅这篇关于使用 getFileSystemInfoForPath 的结果的帖子。因此,除非您只想知道某个卷是否位于可移动媒体上,否则您需要使用另一种技术。

您真正要检查的是卷的连接总线类型。Firewire、USB、Thunderbolt 等在您的意思上是不可安装的。如果您选择卷并按下“连接总线”下的“信息”按钮,您可以在“磁盘工具”中看到此信息。以编程方式获取这些信息要困难得多,据我所知,只有使用 IOKit 才有可能。详细信息在 Apple 关于从应用程序访问硬件的文档中。

于 2012-07-24T22:48:37.800 回答
0

您可以使用“diskutil”的命令行版本的磁盘工具应用程序,使用参数“list”和管道输出运行它并将其放入您的程序中(不需要使用 cocoa)。

于 2012-08-29T10:14:16.750 回答