如何在Mac OS X上防止在操作期间弹出磁盘?

6
我有一个长时间运行的任务,需要在已挂载的USB驱动器上执行一系列文件操作,并且我希望在此过程中防止用户从Finder(或其他地方)弹出驱动器。有一个“取消”按钮可以随时结束任务。
我原以为在任务期间保持已挂载卷上的文件句柄打开就可以解决问题,但它并没有起作用。
这是我尝试的方法(省略了错误处理):
NSString *tempFilePath = @"/Volumes/myVolume/.myTempFile";
if ([[NSFileManager defaultManager] fileExistsAtPath:tempFilePath] == NO) {
    [[NSFileManager defaultManager] createFileAtPath:tempFilePath contents:nil attributes:nil]
}

_tempFile = [NSFileHandle fileHandleForWritingAtPath:tempFilePath];

有什么想法可以确保音量不被弹出?

不想打破你的幻想,但如果有人拔掉他们的USB驱动器怎么办?如果驱动器是硬件驱动的,那么防止它被弹出是不可能的。为什么你不能给用户一个非常严厉的警告,告诉他们不应该弹出驱动器,否则操作将失败? - Jaime Garcia
我确实意识到我们无法完全防止意外断开连接。尽可能地,我希望用户被迫做出有意识的决定来停止操作,以便他们稍后能够理解为什么某些功能无法正常工作。 - mcsheffrey
@ferrari fan:mcsheffrey想要的很有用,因为用户可能会忘记这个任务没有完成,“保留”磁盘某种程度上有助于防止意外弹出。 - mohsenr
@ferrarifan 如果有人“随便拔掉”他们的USB驱动器,Finder将会出现一个可怕的警告消息,提醒可能会丢失一些数据,并且永远不要再这样做了。 - Abhi Beckert
2个回答

10
你需要使用磁盘仲裁API,更具体地说是DARegisterDiskUnmountApprovalCallback。
你可以通过DADisk.h中提供的函数创建DADiskRef
当回调被调用时,你可以决定是否阻止卸载。以下是一个人为的例子:
DADissenterRef myUnmountApprovalCallback(DADiskRef disk, void *context)
{
    DADissenterRef result = NULL; // NULL means approval
    if (stillWorking) {
        // This is released by the caller, according to the docs
        result = DADissenterCreate(kCFAllocatorDefault, kDAReturnBusy, CFSTR("<Your App> is busy writing to this device. Please cancel the operation first.");
    }
    return result;
}

正如评论中所指出的,这并不能防止任何人随意拔掉插头,但它会在显式卸载时通知您。


0

您正在寻找磁盘仲裁(或DiskArb)框架API。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接