如何将桌面目录的文件路径作为macOS上的字符串获取。 我需要在纯C或一些C级框架中完成它。
答案 0 :(得分:0)
如果你坚持只使用C(为什么?),那么你唯一的选择就是使用弃用的API:
#include <limits.h>
#include <CoreServices/CoreServices.h>
...
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 <limits.h>
#include <NSSystemDirectories.h>
char path[PATH_MAX];
NSSearchPathEnumerationState state = NSStartSearchPathEnumeration(NSDesktopDirectory, NSUserDomainMask);
while (state = NSGetNextSearchPathEnumeration(state, path))
{
// Handle path
}
API的形式是它可以返回多个结果(每次循环迭代一次),但是你应该只获得一个特定用途。在这种情况下,您可以将while
更改为if
。
请注意,使用此API,用户域中目录的返回路径可能会使用&#34;〜&#34;而不是用户主目录的绝对路径。你必须自己解决这个问题。
答案 1 :(得分:0)
这是一个简短的功能,它可以在更多基于Unix的系统上运行,而不仅仅是macOS,并返回当前用户的桌面文件夹:
#include <limits.h>
#include <stdlib.h>
/**
* 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;
}
路径只会计算一次。
如果多次调用该函数,将返回旧结果(不是线程安全的,除非第一次调用受到保护)。
答案 2 :(得分:0)
我以这种方式使用Objective-C结束了:
//
// main.m
// search_path_for_dir
//
// Created by Michal Ziobro on 23/09/2016.
// Copyright © 2016 Michal Ziobro. All rights reserved.
//
#import <Foundation/Foundation.h>
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);
}