我想以编程方式更改使用OSXFUSE(以前称为MacFUSE)实现的堆叠文件系统的音量图标。该图标需要反映已安装文件系统的状态。
我一直在尝试的方法是将/.VolumeIcon.icns的请求映射到应用程序包中的相应图标。然后将更改通知发送到文件系统,以获取实际路径(路径)和装载路径(mountPath)。
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: @"/Volumes"];
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: [mountPath stringByDeletingLastPathComponent]];
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: mountPath];
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: [path stringByDeletingLastPathComponent]];
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: path];
FNNotifyByPath([[[mountPath stringByDeletingLastPathComponent] dataUsingEncoding:NSUTF8StringEncoding] bytes], kFNDirectoryModifiedMessage, kNilOptions);
FNNotifyByPath([[[path stringByDeletingLastPathComponent] dataUsingEncoding:NSUTF8StringEncoding] bytes], kFNDirectoryModifiedMessage, kNilOptions);
FNNotifyByPath([[@"/Volumes" dataUsingEncoding:NSUTF8StringEncoding] bytes], kFNDirectoryModifiedMessage, kNilOptions);
单步调试我可以看到这个代码被点击但是映射/.VolumeIcon.icns的代码很少被调用,而且从不响应这些通知。
答案 0 :(得分:3)
我认为简短的回答是,你运气不好。很长的答案是,虽然OSXFUSE项目与Fuse4X项目不同,但它们都来自相同的来源,而Fuse4X在其常见问题解答中有关于音量图标的说法:
问题4.1。为什么Fuse4X卷显示“服务器”(或“网络”) 卷“)图标?
答:确切地说,默认情况下,Fuse4X卷显示为非本地 不幸的是,Finder将其视为“服务器”。 这是一个很好的问题,为什么Fuse4X通常将其卷标记为 外地。有些人认为在基于磁盘的文件的情况下 系统,Fuse4X必须将音量标记为本地。好吧,让我们看看。
对于在Mac OS X上本地的vfs,您需要一个“真正的”磁盘设备 - a / dev / disk *样式节点。在Fuse4X的情况下,这样一个真正的磁盘设备节点 有问题:在挂载时,对于本地卷,内核会 本身打开设备节点并将其传递给Fuse4X。这样做, 内核将确保该设备当前未被使用(for 一,禁止多个相同设备的安装)。有时候是这样的 在控制传递到Fuse4X之前,可以继续安装。这个会 如果整个文件系统都存在于内核中,那就没问题了 Fuse4X的情况下,用户空间文件系统程序也想要 (专门)打开磁盘设备。
答案 1 :(得分:1)
- (BOOL)setAsCustomIconForVolume:(NString *)path;
{
FSref FSRefpath = convertoFsref(path);
// filename for custom icon is ".VolumeIcon.icns"
NSString *iconPath = [path stringByAppendingPathComponent:@".VolumeIcon.icns"];
// remove any existing file first.
[self writeToFile:iconPath];
FSSetHasCustomIcon(FSRefpath);
// rebuild volumeList
return YES;
}
OSErr FSSetHasCustomIcon(
const FSRef *ref)
{
return ( FSChangeFinderFlags(ref, true, kHasCustomIcon) );
}
OSErr FSChangeFinderFlags(
const FSRef *ref,
Boolean setBits,
UInt16 flagBits)
{
OSErr result;
FSCatalogInfo catalogInfo;
FSRef parentRef;
/* get the current finderInfo */
result = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, &parentRef);
require_noerr(result, FSGetCatalogInfo);
/* set or clear the appropriate bits in the finderInfo.finderFlags */
if ( setBits )
{
/* OR in the bits */
((FileInfo *)&catalogInfo.finderInfo)->finderFlags |= flagBits;
}
else
{
/* AND out the bits */
((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~flagBits;
}
/* save the modified finderInfo */
result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
require_noerr(result, FSSetCatalogInfo);
FSSetCatalogInfo:
FSGetCatalogInfo:
return ( result );
}