Skip to content

Instantly share code, notes, and snippets.

@upsuper
Created January 24, 2012 16:57
Show Gist options
  • Save upsuper/1671124 to your computer and use it in GitHub Desktop.
Save upsuper/1671124 to your computer and use it in GitHub Desktop.
Set directory icon on Mac
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <CoreServices/CoreServices.h>
#include "directory_icon.h"
int setDirectoryIcon(const char *dirName, const char *iconData, size_t iconSize)
{
const int kResidIcon = -16455;
const OSType kRsrcType = 'icns';
const char *kIconName = "/Icon\r";
OSErr oserr;
/* Construct icon filename */
size_t filenameLength = strlen(dirName) + strlen(kIconName);
char *iconFilename = (char *)malloc(filenameLength + 1);
strcpy(iconFilename, dirName);
char *p = &iconFilename[strlen(dirName) - 1];
while (*p == '/')
*(p--) = '\0';
strcat(iconFilename, kIconName);
/* Make sure it exists */
FILE *iconFile = fopen(iconFilename, "w");
fclose(iconFile);
/* Open or create resource fork */
FSRef iconRef;
FSPathMakeRef((StringPtr)iconFilename, &iconRef, NULL);
free(iconFilename);
short iconRefNum = FSOpenResFile(&iconRef, fsRdWrPerm);
HFSUniStr255 forkName;
if (ResError() == eofErr)
if (FSGetResourceForkName(&forkName) == noErr)
if (FSCreateResourceFork(&iconRef, forkName.length, forkName.unicode, 0) == noErr)
iconRefNum = FSOpenResFile(&iconRef, fsRdWrPerm);
if ((oserr = ResError()) != noErr)
return oserr;
/* Write icon data to resource fork */
Handle hand;
if (! GetResource(kRsrcType, kResidIcon))
if (PtrToHand(iconData, &hand, iconSize) == noErr)
AddResource(hand, kRsrcType, kResidIcon, (StringPtr)"\pApplication icons");
CloseResFile(iconRefNum);
if ((oserr = ResError()) != noErr)
return oserr;
/* Set icon file info */
FSCatalogInfo catalogInfo;
FileInfo *fileInfo;
FSGetCatalogInfo(&iconRef, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL);
fileInfo = (FileInfo *)&catalogInfo.finderInfo;
fileInfo->finderFlags |= kIsInvisible;
fileInfo->fileCreator ='MACS';
fileInfo->fileType = 'icon';
FSSetCatalogInfo(&iconRef, kFSCatInfoFinderInfo, &catalogInfo);
/* Set directory has custom icon */
FSRef dirRef;
FSPathMakeRef((StringPtr)dirName, &dirRef, NULL);
FSGetCatalogInfo(&dirRef, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL);
fileInfo = (FileInfo *)&catalogInfo.finderInfo;
fileInfo->finderFlags |= kHasCustomIcon;
FSSetCatalogInfo(&dirRef, kFSCatInfoFinderInfo, &catalogInfo);
return 0;
}
#ifndef directory_icon_h
#define directory_icon_h
int setDirectoryIcon(const char *dirName, const char *iconData, size_t iconSize);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment