从沙盒命令行应用程序获取当前工作目录
Getting current working directory from a Sandboxed command-line app
我现在正在尝试对用 Objective-C 编写的命令行应用程序进行沙盒处理。
问题
当应用程序未被沙盒化时,我可以使用 [[NSFileManager defaultManager] currentDirectoryPath]
获取用户调用应用程序的目录。
但是,在沙盒之后,无论从何处调用命令行应用程序,该应用程序始终 returns 当前目录 /Users/{MY_ACCOUNT}/Library/Containers/{BUNDLE_IDENTIFIER}/Data
。
示例代码
实际上,我想知道用户作为命令参数传递的文件的绝对路径。
因此,例如,当我这样调用我的命令行应用程序时:
$ pwd
/Users/MY_ACCOUNT/Desktop
$ ./foo/my_executable subfolder/myfile.txt
以下部分:
NSURL *url = [NSURL fileURLWithFileSystemRepresentation:argv[1] isDirectory:NO relativeToURL:nil];
printf("path: %s\n", [[url absoluteURL] fileSystemRepresentation]);
returns 在 非沙盒化 应用上正确:
path: /Users/MY_ACCOUNT/Desktop/subfolder/myfile.txt
但在 沙盒化 应用上:
path: /Users/MY_ACCOUNT/Library/Containers/BUNDLE_IDENTIFIER/Data/subfolder/myfile.txt
这当然是不正确的。
问题
是否有其他方法可以在沙盒命令行应用程序中获取传递的文件路径参数的正确完整路径?
或者这是不可能的,我最好放弃我的应用程序沙箱?
解决方案
最后,我自己找到了一个解决方案。
[NSProcessInfo processInfo]
中的 environment
属性 具有正确的当前用户工作目录,即使该应用已被沙盒化。
NSDictionary *env = [[NSProcessInfo processInfo] environment];
NSString *currentPath = env[@"PWD"];
至少,当我调用 Terminal.app 中的命令时,它起作用了。我不确定这个 PWD
是否一直存在。
此外,正如@daij-djan 在下面指出的那样,我们甚至没有给定参数的读取权限。不过好歹这个问题已经解决了
(如果有人知道如何读取作为参数传递的路径的文件,请告诉我作为答案!)
这会获取当前应用程序的沙盒路径。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *rootPath = [paths objectAtIndex:0];
请记住,在上面的代码 returns 沙箱路径之前,必须在项目设置中打开 "Sandbox"。
AFAIK(我刚才试过这个,所以事情可能已经改变了——虽然我不认为)
即使您知道它们的实际位置,也无法访问通过命令行参数传递的路径:/
===> 所以:这就是我的答案.. 恐怕这是毫无意义的,因为它不起作用
我现在正在尝试对用 Objective-C 编写的命令行应用程序进行沙盒处理。
问题
当应用程序未被沙盒化时,我可以使用 [[NSFileManager defaultManager] currentDirectoryPath]
获取用户调用应用程序的目录。
但是,在沙盒之后,无论从何处调用命令行应用程序,该应用程序始终 returns 当前目录 /Users/{MY_ACCOUNT}/Library/Containers/{BUNDLE_IDENTIFIER}/Data
。
示例代码
实际上,我想知道用户作为命令参数传递的文件的绝对路径。
因此,例如,当我这样调用我的命令行应用程序时:
$ pwd
/Users/MY_ACCOUNT/Desktop
$ ./foo/my_executable subfolder/myfile.txt
以下部分:
NSURL *url = [NSURL fileURLWithFileSystemRepresentation:argv[1] isDirectory:NO relativeToURL:nil];
printf("path: %s\n", [[url absoluteURL] fileSystemRepresentation]);
returns 在 非沙盒化 应用上正确:
path: /Users/MY_ACCOUNT/Desktop/subfolder/myfile.txt
但在 沙盒化 应用上:
path: /Users/MY_ACCOUNT/Library/Containers/BUNDLE_IDENTIFIER/Data/subfolder/myfile.txt
这当然是不正确的。
问题
是否有其他方法可以在沙盒命令行应用程序中获取传递的文件路径参数的正确完整路径? 或者这是不可能的,我最好放弃我的应用程序沙箱?
解决方案
最后,我自己找到了一个解决方案。
[NSProcessInfo processInfo]
中的 environment
属性 具有正确的当前用户工作目录,即使该应用已被沙盒化。
NSDictionary *env = [[NSProcessInfo processInfo] environment];
NSString *currentPath = env[@"PWD"];
至少,当我调用 Terminal.app 中的命令时,它起作用了。我不确定这个 PWD
是否一直存在。
此外,正如@daij-djan 在下面指出的那样,我们甚至没有给定参数的读取权限。不过好歹这个问题已经解决了
(如果有人知道如何读取作为参数传递的路径的文件,请告诉我作为答案!)
这会获取当前应用程序的沙盒路径。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *rootPath = [paths objectAtIndex:0];
请记住,在上面的代码 returns 沙箱路径之前,必须在项目设置中打开 "Sandbox"。
AFAIK(我刚才试过这个,所以事情可能已经改变了——虽然我不认为)
即使您知道它们的实际位置,也无法访问通过命令行参数传递的路径:/
===> 所以:这就是我的答案.. 恐怕这是毫无意义的,因为它不起作用