开发者

Finding "~/Library/Application Support" from C++?

I've written a GTKmm application and I'm trying to create some OS X enhancements. I'd like to store my configuration file in the App开发者_如何学Pythonlication Support/myApp folder, however, I can't figure out the proper way to locate this folder.

I've tried looking through the Core Foundation library (that I'm using to get my myApp.app path) but I can't find anything.


Proper way to do it in C/C++:

#include <CoreServices/CoreServices.h>

FSRef ref;
OSType folderType = kApplicationSupportFolderType;
char path[PATH_MAX];

FSFindFolder( kUserDomain, folderType, kCreateFolder, &ref );

FSRefMakePath( &ref, (UInt8*)&path, PATH_MAX );

// You now have ~/Library/Application Support stored in 'path'

Naturally, those are very old APIs and their use is no longer recommended by Apple. Despite that it gets the job done if you want to avoid Objective-C completely in your codebase.


It appears that the function to use for this is NSSearchPathForDirectoriesInDomains (or some other functions listed on the same page) with NSApplicationSupportDirectory as the argument.


In BSD Unix, included in OS-X, you can get the home directory of the user running the program with this:

struct passwd *p = getpwuid(getuid());  /* defined in pwd.h, and requires sys/types.h */ 
char *home = p->pw_dir;

Using this, you can then construct the path using this in place of ~

char *my_app_name = "WHATEVER";
char app_support[MAXPATHLEN];  /* defined in sys/param.h */
snprintf(app_support,MAXPATHLEN,"%s/Library/Application Support/%s", home, my_app_name);


A solution that is not deprecated

#include <sysdir.h>  // for sysdir_start_search_path_enumeration
#include <glob.h>    // for glob needed to expand ~ to user dir


std::string expandTilde(const char* str) {
    if (!str) return {};

    glob_t globbuf;
    if (glob(str, GLOB_TILDE, nullptr, &globbuf) == 0) {
        std::string result(globbuf.gl_pathv[0]);
        globfree(&globbuf);
        return result;
    } else {
        throw std::exception("Unable to expand tilde");
    }
}

std::string settingsPath(const char* str) {
    char path[PATH_MAX];
    auto state = sysdir_start_search_path_enumeration(SYSDIR_DIRECTORY_APPLICATION_SUPPORT,
                                                      SYSDIR_DOMAIN_MASK_USER);
    if ((state = sysdir_get_next_search_path_enumeration(state, path))) {
        return expandTilde(path);
    } else {
        throw std::exception("Failed to get settings folder");
    }
}


This is not application support but you probably don't want to store files there anyways. Instead use the directory that you get from calling "HOME":

You can use the C-function getenv: char *home = getenv("HOME");

and to get the C++ string use: string(home)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜