2012-02-10 13 views
12

Quiero cambiar mediante programación el icono de volumen para un sistema de archivos apilados implementado usando OSXFUSE (anteriormente MacFUSE). El icono debe reflejar el estado de un sistema de archivos montado.¿Es posible cambiar de forma programática el icono de volumen en una unidad montada en Mac OS X?

El enfoque que he estado tratando de poner en práctica es mapear solicitudes para /.VolumeIcon.icns al icono correspondiente en el paquete de la aplicación. A continuación, enviando notificaciones de cambio al sistema de archivos para la ruta real (ruta) y la ruta de montaje (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); 

Entrar por el depurador puedo ver el código de ser golpeado, pero el código para mapear los /.VolumeIcon.icns es llamado con frecuencia y nunca en respuesta a estas notificaciones.

+0

Ha intentado borrar archivos .DS_Store oculto? –

+1

No estoy seguro de que afecte el icono. Pero en cualquier caso, soy reacio a seguir esta ruta, ya que significa borrar la configuración de visualización de la carpeta elegida por el usuario. –

+0

@Aditya: Intenté su sugerencia, pero eliminar el archivo .DS_Store no tiene ningún impacto en el icono de volumen que se muestra en el escritorio. –

Respuesta

3

Creo que la respuesta corta es que no tiene suerte. La respuesta larga es OSXFUSE mientras que el proyecto es diferente que el proyecto Fuse4X, los dos están derivan de la misma fuente, y Fuse4X tiene esto que decir acerca de los iconos de volumen en sus preguntas más frecuentes:

Q 4.1. ¿Por qué aparecen los volúmenes de Fuse4X con los iconos "servidor" (o "red volumen")?

R: Para ser precisos, de forma predeterminada los volúmenes de Fuse4X aparecen como volúmenes no locales , que el Finder desafortunadamente trata igual que "servidores". Es una buena pregunta sobre por qué Fuse4X normalmente etiqueta sus volúmenes como no local. Algunas personas piensan que en el caso de los sistemas de archivos basados ​​en disco , Fuse4X debe etiquetar el volumen como local. Bueno, veamos.

Para que un vfs sea local en Mac OS X, necesita un dispositivo de disco "real": un nodo de estilo /dev/disk *. Tal nodo real de dispositivo de disco en el caso de Fuse4X es problemático: en el momento del montaje, para un volumen local, el kernel abriría el nodo del dispositivo y lo pasaría a Fuse4X en el propio . Al hacerlo, el kernel se aseguraría de que el dispositivo no esté actualmente en uso (para uno, para no permitir múltiples montajes del mismo dispositivo). Esto sucede antes de que el control pase a Fuse4X y el montaje puede continuar. Esto sería si todo el sistema de archivos vivió en el kernel, pero en el caso de Fuse4X, el programa de sistema de archivos de espacio de usuario también querría (exclusivamente) abrir el dispositivo de disco.

1

Eche un vistazo a 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

Cuestiones relacionadas