12

OSXFUSE(以前のMacFUSE)を使用して実装されたスタックファイルシステムのボリュームアイコンをプログラムで変更したい。アイコンは、マウントされたファイルシステムの状態を反映している必要があります。

私が機能させようとしているアプローチは、/。VolumeIcon.icnsのリクエストをアプリケーションバンドル内の適切なアイコンにマップすることです。次に、実際のパス(path)とマウントパス(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をマップするコードは頻繁に呼び出されず、これらの通知に応答することはありません。

4

2 に答える 2

3

簡単に言えば、あなたは運が悪いということだと思います。長い答えは、OSXFUSEプロジェクトはFuse4Xプロジェクトとは異なりますが、どちらも同じソースから派生しているため、Fuse4XのFAQでボリュームアイコンについて次のように述べています。

Q4.1。Fuse4Xボリュームが「サーバー」(または「ネットワークボリューム」)アイコンで表示されるのはなぜですか?

A:正確には、デフォルトではFuse4Xボリュームは非ローカルボリュームとして表示されますが、残念ながらFinderはこれを「サーバー」と同じように扱います。Fuse4Xが通常そのボリュームを非ローカルとしてタグ付けする理由については良い質問です。ディスクベースのファイルシステムの場合、Fuse4Xはボリュームにローカルのタグを付ける必要があると考える人もいます。さて、見てみましょう。

vfsをMacOSXでローカルにするには、「実際の」ディスクデバイス(/ dev / disk *スタイルのノード)が必要です。Fuse4Xの場合、このような実ディスクデバイスノードには問題があります。マウント時に、ローカルボリュームの場合、カーネル自体がデバイスノードを開き、Fuse4Xに渡します。そうすることで、カーネルはデバイスが現在使用されていないことを確認します(たとえば、同じデバイスの複数のマウントを禁止します)。これは、制御がFuse4Xに渡され、マウントを続行できるようになる前に発生します。ファイルシステム全体がカーネルに存在する場合、これは問題ありませんでしたが、Fuse4Xの場合、ユーザースペースファイルシステムプログラムも(排他的に)ディスクデバイスを開きたいと思うでしょう。

于 2012-02-14T16:24:41.650 に答える
2

パスファインダーのソースコードを見てください。

- (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 );
}  

NTVolumeNotificationMgr
NTIconFamily

于 2012-02-16T10:31:44.650 に答える