OS X:如何在macOS上获取Desktop目录的路径?

如何将文件路径作为macOS上的字符串获取到Desktop目录。 我需要在纯C或一些C级框架中完成它。

如果你坚持只使用C(为什么?),那么你唯一的选择就是使用不推荐使用的API:

 #include  #include  ... FSRef fsref; UInt8 path[PATH_MAX]; if (FSFindFolder(kUserDomain, kDesktopFolderType, kDontCreateFolder, &fsref) == noErr && FSRefMakePath(&fsref, path, sizeof(path)) == noErr) { // Make use of path } 

如果需要CFURL而不是路径,则可以使用CFURLCreateFromFSRef()而不是FSRefMakePath()

实际上,在研究这个时,我找到了一个我不知道的API。 显然,你可以使用它,它显然来自Cocoa,但只使用C类型:

 #include  #include  char path[PATH_MAX]; NSSearchPathEnumerationState state = NSStartSearchPathEnumeration(NSDesktopDirectory, NSUserDomainMask); while (state = NSGetNextSearchPathEnumeration(state, path)) { // Handle path } 

API的forms是它可以返回多个结果(循环的每次迭代都有一个),但是你应该只获得一个特定用途。 在这种情况下,您可以将while更改为和if

请注意,使用此API,用户域中目录的返回路径可能使用“〜”而不是用户主目录的绝对路径。 你必须自己解决这个问题。

这是一个简短的函数,它可以在更多基于Unix的系统上运行,而不仅仅是macOS,并返回当前用户的桌面文件夹:

 #include  #include  /** * Returns the path to the current user's desktop. */ char *path2desktop(void) { static char real_public_path[PATH_MAX + 1] = {0}; if (real_public_path[0]) return real_public_path; strcpy(real_public_path, getenv("HOME")); memcpy(real_public_path + strlen(real_public_path), "/Desktop", 8); return real_public_path; } 

该路径仅计算一次。

如果多次调用该函数,将返回旧结果(不是线程安全的,除非第一次调用受到保护)。

我以这种方式使用Objective-C结束了:

 // // main.m // search_path_for_dir // // Created by Michal Ziobro on 23/09/2016. // Copyright © 2016 Michal Ziobro. All rights reserved. // #import  int main(int argc, const char * argv[]) { if(argc != 3) return 1; @autoreleasepool { NSArray *paths = NSSearchPathForDirectoriesInDomains(atoi(argv[1]), atoi(argv[2]), YES); NSString *path = [paths objectAtIndex:0]; [path writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil]; } return 0; } 

而且从命令行我可以这样执行这个程序:

 ./search_path_for_dir 12 1 

12 – NSDesktopDirectory

1 – NSUserDomainMask

我在C中使用脚本从命令行执行此程序并检索其输出。

这是调用这个迷你Cocoa应用程序的C示例:

 CFStringRef FSGetFilePath(int directory, int domainMask) { CFStringRef scheme = CFSTR("file:///"); CFStringRef absolutePath = FSGetAbsolutePath(directory, domainMask); CFMutableStringRef filePath = CFStringCreateMutable(NULL, 0); if (filePath) { CFStringAppend(filePath, scheme); CFStringAppend(filePath, absolutePath); } CFRelease(scheme); CFRelease(absolutePath); return filePath; } CFStringRef FSGetAbsolutePath(int directory, int domainMask) { char path_cmd[BUF_SIZE]; sprintf(path_cmd, "./tools/search_path_for_dir %d %d", directory, domainMask); char *path = exec_cmd(path_cmd); return CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8); }