2012-02-10 45 views
12

Tôi muốn thay đổi biểu tượng âm lượng theo chương trình cho hệ thống tệp xếp chồng được triển khai bằng cách sử dụng OSXFUSE (trước đây là MacFUSE). Biểu tượng cần phản ánh trạng thái của hệ thống tệp được gắn kết.Có thể lập trình thay đổi biểu tượng âm lượng trên ổ đĩa gắn trên Mac OS X không?

Cách tiếp cận mà tôi đang cố gắng làm việc là ánh xạ các yêu cầu cho /.VolumeIcon.icns đến biểu tượng thích hợp trong gói ứng dụng. Sau đó gửi thông báo thay đổi đến hệ thống tệp cho đường dẫn thực tế (đường dẫn) và đường dẫn gắn kết (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); 

Bước qua debugger tôi có thể thấy mã này bị trúng nhưng mã để lập bản đồ /.VolumeIcon.icns được gọi không thường xuyên và không bao giờ để đáp ứng với các thông báo này.

+0

Các bạn đã thử xóa tập tin .DS_Store ẩn? –

+1

Tôi không chắc chắn điều đó sẽ ảnh hưởng đến biểu tượng. Nhưng trong mọi trường hợp tôi không muốn đi xuống con đường này vì nó có nghĩa là xóa các cài đặt hiển thị thư mục do người dùng chọn. –

+0

@Aditya - Tôi đã thử đề xuất của bạn nhưng xóa tệp .DS_Store không ảnh hưởng đến biểu tượng âm lượng được hiển thị trên màn hình. –

Trả lời

3

Tôi nghĩ câu trả lời ngắn gọn là bạn không may mắn. Câu trả lời dài là trong khi dự án OSXFUSE khác với dự án Fuse4X, cả hai đều có nguồn gốc từ cùng một nguồn, và Fuse4X có điều này để nói về các biểu tượng âm lượng trong Câu hỏi thường gặp của họ:

Q 4.1. Tại sao khối lượng Fuse4X hiển thị với biểu tượng "máy chủ" (hoặc "mạng khối lượng")?

A: Để chính xác, theo mặc định, khối lượng Fuse4X hiển thị dưới dạng khối lượng không trung thực, mà Finder không may được coi là "máy chủ". Đó là một câu hỏi hay về lý do tại sao Fuse4X thường gắn thẻ khối lượng của nó là không tập trung. Một số người nghĩ rằng trong trường hợp hệ thống tập tin dựa trên đĩa , Fuse4X phải gắn thẻ âm lượng là cục bộ. Vâng, chúng ta hãy xem.

Đối với một vfs là cục bộ trên Mac OS X, bạn cần một thiết bị đĩa "thực" - nút kiểu /dev/disk *. Một nút thiết bị đĩa thực trong trường hợp của Fuse4X là có vấn đề: tại thời điểm gắn kết, đối với một ổ đĩa cục bộ, hạt nhân sẽ tự động mở nút thiết bị và chuyển nó tới Fuse4X . Khi làm như vậy, hạt nhân sẽ đảm bảo rằng thiết bị hiện không được sử dụng (đối với một, để không cho phép nhiều kết nối của cùng một thiết bị). Điều này xảy ra trước khi điều khiển chuyển tới Fuse4X và có thể tiến hành lắp đặt. Điều này sẽ là tốt nếu toàn bộ hệ thống tập tin sống trong hạt nhân, nhưng trong trường hợp của Fuse4X, chương trình hệ thống tệp người dùng cũng sẽ muốn (độc quyền) mở thiết bị đĩa.

1

Hãy xem path finder source code.

- (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

Các vấn đề liên quan