列出所有驱动器/分区,并获得/ dev / rdisc设备与Cocoa [英] List all drives/partitions, and get /dev/rdisc device with Cocoa
问题描述
有没有办法列出可用的驱动器,类似于磁盘工具,并获得相关的 / dev / rdisk *
设备?
磁盘工具可以访问此数据 - 当您选择一个驱动器并按下信息按钮时,它列出..
分区映射方案:GUID分区表
磁盘标识符:disk0
媒体名称:Hitachi HTS541612J9SA00媒体
..或选择一个分区:
磁盘标识符:disk0s3
:/ Volumes / BOOTCAMP
有Cocoa API吗?
As groundhog指出, IORegistry
确实是所有与设备相关的东西的源头。 IOKit
文档非常详细和有用;您应该从 IOKit基础知识,然后点击从应用程序访问硬件,然后最后查看存储设备的设备文件访问指南如果您想以BSD方式获取信息。
在这种情况下,您可以使磁盘仲裁框架做一些繁重的查询IO注册表和注册通知。这节省了很多代码,但是要做你想做的一切,你最终需要使用 IOKit
函数与底层 IOMedia
object(请参阅
DADiskCopyIOMedia()
)。
您可以在表示IO注册表中的磁盘的 IOMedia
对象周围编写一个Cocoa包装,然后使用对象控制器将属性绑定到您的UI。 p>
以下是通过磁盘仲裁框架注册磁盘外观通知以开始使用的示例:
// gcc -Wall -framework Foundation -framework DiskArbitration disk_arbiter.m -o disk_arbiter
/ * @file disk_arbiter.m
* @author Jeremy W. Sherman
* @date 2009-10-03
*
*演示从
* DiskArbitration框架注册磁盘出现的通知。
*
*注意,在注册时,所有
*已经出现的磁盘都会传递磁盘出现的通知,然后
*会在事件实际发生之后涓流。
* /
#import< Foundation / Foundation.h>
#import< DiskArbitration / DiskArbitration.h>
#import< signal.h>
sig_atomic_t sShouldExit = 0;
static void RegisterInterruptHandler(void);
static void HandleInterrupt(int);
static void OnDiskAppeared(DADiskRef disk,void * __ attribute __((__ unused__)));
int
main(void){
CFStringRef const kDARunLoopMode = kCFRunLoopDefaultMode;
RegisterInterruptHandler();
//设置会话。
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DARegisterDiskAppearedCallback(session,NULL / *所有磁盘* /,OnDiskAppeared,(void *)NULL);
DASessionScheduleWithRunLoop(session,CFRunLoopGetCurrent(),kDARunLoopMode);
//运行事件循环。
printf(Starting ... \\\
(Press Ctrl-C to exit。)\\\
\\\
);
const Boolean kAndReturnAfterHandlingSource = TRUE;
const CFTimeInterval kForOneSecond = 1.0;
while(!sShouldExit)
(void)CFRunLoopRunInMode(kCFRunLoopDefaultMode,
kForOneSecond,kAndReturnAfterHandlingSource);
//退出并退出。
printf(\\\
Exiting ... \\\
);
DASessionUnscheduleFromRunLoop(session,CFRunLoopGetCurrent(),kDARunLoopMode);
CFRelease(session);
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
static void
RegisterInterruptHandler(void){
struct sigaction sigact;
sigact.sa_handler = HandleInterrupt;
(void)sigaction(SIGINT,& sigact,NULL / * discard previous handler * /);
}
static void
HandleInterrupt(int __attribute __((__ unused__))signo){
sShouldExit = 1;
RegisterInterruptHandler();
}
static void
OnDiskAppeared(DADiskRef disk,void * __ attribute __((__ unused__))ctx){
printf出现!\\\
);
CFShow(disk);
}
以下是示例运行的输出:
$ ./disk_arbiter
正在启动...
(按Ctrl-C退出)
,磁盘出现!
< DADisk 0x104f80 [0xa01c01a0]> {id = / dev / disk3}
Lo,磁盘出现!
< DADisk 0x105b40 [0xa01c01a0]> {id = / dev / disk2s1}
出现一个磁盘!
< DADisk 0x105ae0 [0xa01c01a0]> {id = / dev / disk2s2}
Lo,磁盘出现!
< DADisk 0x105b60 [0xa01c01a0]> {id = / dev / disk2}
Lo,磁盘出现!
< DADisk 0x105950 [0xa01c01a0]> {id = / dev / disk1}
Lo,磁盘出现!
< DADisk 0x105bc0 [0xa01c01a0]> {id = / dev / disk1s1}
Lo,磁盘出现!
< DADisk 0x105540 [0xa01c01a0]> {id = / dev / disk0}
Lo,磁盘出现!
< DADisk 0x105660 [0xa01c01a0]> {id = / dev / disk0s1}
Lo,磁盘出现!
< DADisk 0x1054a0 [0xa01c01a0]> {id = / dev / disk0s2}
^ C
退出...
Is there a way to list available drives, similar to Disk Utility, and get the associated /dev/rdisk*
device for it?
Disk Utility has access to this data - when you select a drive and press the Info button, it lists..
Partition Map Scheme : GUID Partition Table
Disk Identifier : disk0
Media Name : Hitachi HTS541612J9SA00 Media
..or select a partition:
Disk Identifier : disk0s3
Mount Point : /Volumes/BOOTCAMP
Is there a Cocoa API to get at this? If so, what is the best way to display this via Interface Builder?
As groundhog points out, the IORegistry
is indeed the go-to source for all things device-related. The IOKit
docs are very detailed and helpful; you should start with IOKit Fundamentals, then hit Accessing Hardware from Applications, then finally check out Device File Access Guide for Storage Devices if you want to get at information the BSD way.
In this case, you can make the Disk Arbitration framework do some of the heavy lifting of querying the IO registry and registering for notifications. This saves a lot of code, but to do everything you want to do, you'll eventually need to use IOKit
functions with the underlying IOMedia
object (see DADiskCopyIOMedia()
).
You could readily write a Cocoa wrapper around the IOMedia
objects that represent the disks in the IO registry, then use object controllers to bind properties to your UI.
Here's an example of registering for disk appearance notifications through the Disk Arbitration framework to get you started:
// gcc -Wall -framework Foundation -framework DiskArbitration disk_arbiter.m -o disk_arbiter
/* @file disk_arbiter.m
* @author Jeremy W. Sherman
* @date 2009-10-03
*
* Demonstrates registering for disk appeared notifications from
* the DiskArbitration framework.
*
* Note that disk appeared notifications are delivered for all
* already-appeared disks at the time of registration, and then
* trickle in as the events actually happen thereafter.
*/
#import <Foundation/Foundation.h>
#import <DiskArbitration/DiskArbitration.h>
#import <signal.h>
sig_atomic_t sShouldExit = 0;
static void RegisterInterruptHandler(void);
static void HandleInterrupt(int);
static void OnDiskAppeared(DADiskRef disk, void *__attribute__((__unused__)));
int
main(void) {
CFStringRef const kDARunLoopMode = kCFRunLoopDefaultMode;
RegisterInterruptHandler();
// Set up session.
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DARegisterDiskAppearedCallback(session, NULL/*all disks*/, OnDiskAppeared, (void *)NULL);
DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kDARunLoopMode);
// Run event loop.
printf("Starting...\n(Press Ctrl-C to exit.)\n\n");
const Boolean kAndReturnAfterHandlingSource = TRUE;
const CFTimeInterval kForOneSecond = 1.0;
while (!sShouldExit)
(void)CFRunLoopRunInMode(kCFRunLoopDefaultMode,
kForOneSecond, kAndReturnAfterHandlingSource);
// Tear down and exit.
printf("\nExiting...\n");
DASessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kDARunLoopMode);
CFRelease(session);
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
static void
RegisterInterruptHandler(void) {
struct sigaction sigact;
sigact.sa_handler = HandleInterrupt;
(void)sigaction(SIGINT, &sigact, NULL/*discard previous handler*/);
}
static void
HandleInterrupt(int __attribute__((__unused__)) signo) {
sShouldExit = 1;
RegisterInterruptHandler();
}
static void
OnDiskAppeared(DADiskRef disk, void *__attribute__((__unused__)) ctx) {
printf("Lo, a disk appears!\n");
CFShow(disk);
}
And here's output from a sample run:
$ ./disk_arbiter
Starting...
(Press Ctrl-C to exit.)
Lo, a disk appears!
<DADisk 0x104f80 [0xa01c01a0]>{id = /dev/disk3}
Lo, a disk appears!
<DADisk 0x105b40 [0xa01c01a0]>{id = /dev/disk2s1}
Lo, a disk appears!
<DADisk 0x105ae0 [0xa01c01a0]>{id = /dev/disk2s2}
Lo, a disk appears!
<DADisk 0x105b60 [0xa01c01a0]>{id = /dev/disk2}
Lo, a disk appears!
<DADisk 0x105950 [0xa01c01a0]>{id = /dev/disk1}
Lo, a disk appears!
<DADisk 0x105bc0 [0xa01c01a0]>{id = /dev/disk1s1}
Lo, a disk appears!
<DADisk 0x105540 [0xa01c01a0]>{id = /dev/disk0}
Lo, a disk appears!
<DADisk 0x105660 [0xa01c01a0]>{id = /dev/disk0s1}
Lo, a disk appears!
<DADisk 0x1054a0 [0xa01c01a0]>{id = /dev/disk0s2}
^C
Exiting...
这篇关于列出所有驱动器/分区,并获得/ dev / rdisc设备与Cocoa的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!