Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ chdir到.app包在C++;macOS应用程序_C++_Macos - Fatal编程技术网

C++ chdir到.app包在C++;macOS应用程序

C++ chdir到.app包在C++;macOS应用程序,c++,macos,C++,Macos,我已经打包了一个应用程序的macOS二进制文件,该应用程序将资源加载到.app捆绑包外部的文件夹中。目录结构如下所示 Foo/ Foo.app/ Contents/ ... resources/ 我想将应用程序的工作目录更改为父目录Foo/,这就是我到目前为止所想到的 #if defined(APPLE) #include "CoreFoundation/CoreFoundation.h" #include <uni

我已经打包了一个应用程序的macOS二进制文件,该应用程序将资源加载到.app捆绑包外部的文件夹中。目录结构如下所示

Foo/
    Foo.app/
        Contents/
            ...
    resources/
我想将应用程序的工作目录更改为父目录
Foo/
,这就是我到目前为止所想到的

#if defined(APPLE)
    #include "CoreFoundation/CoreFoundation.h"
    #include <unistd.h>
    #include <libgen.h>
#endif


int main() {
#if defined(APPLE)
    // macOS workaround for setting the working directory to the location of the .app
    {
        CFBundleRef bundle = CFBundleGetMainBundle();
        CFURLRef bundleURL = CFBundleCopyBundleURL(bundle);
        char path[PATH_MAX];
        Boolean success = CFURLGetFileSystemRepresentation(bundleURL, TRUE, (UInt8 *)path, PATH_MAX);
        assert(success);
        CFRelease(bundleURL);

        chdir(dirname(path));
    }
#endif

    ...
}
#如果定义(苹果)
#包括“CoreFoundation/CoreFoundation.h”
#包括
#包括
#恩迪夫
int main(){
#如有定义(苹果)
//macOS解决方案,用于将工作目录设置为.app的位置
{
Cbundleref bundle=CbundleGetMainBundle();
CFURLRef bundleURL=CFBundleCopyBundleURL(bundle);
字符路径[path_MAX];
Boolean success=CFURLGetFileSystemRepresentation(bundleURL,TRUE,(UInt8*)路径,路径_MAX);
断言(成功);
CFRelease(bundleul);
chdir(dirname(path));
}
#恩迪夫
...
}
这在macOS 10.7和10.10(这是我必须测试的全部)上似乎是可行的,但在10.12上,用户报告没有加载资源,因此我怀疑上述黑客不再正常工作


是否有更好的方法更改到正在运行的.app捆绑包的目录?

这里是另一种方法,但我尚未在所有macOS版本上进行测试。我希望这对某人有所帮助,但在我确定这是最好的方法之前,我不会接受它作为答案

#include <unistd.h> // for chdir
#include <libgen.h> // for dirname
#include <mach-o/dyld.h> // for _NSGetExecutablePath
#include <limits.h> // for PATH_MAX?

char path[PATH_MAX];
uint32_t pathLen = sizeof(path);
int err = _NSGetExecutablePath(path, &pathLen);
assert(!err);

// Switch to the directory of the actual binary
chdir(dirname(path));
// and then go up three directories to get to the folder of the .app bundle
chdir("../../../");
#包含//用于chdir
#包含//作为目录名
#包含//for NSGetExecutablePath
#包括//路径\最大值?
字符路径[path_MAX];
uint32_t pathLen=sizeof(路径);
int err=\n获取可执行路径(路径,&pathLen);
断言(!err);
//切换到实际二进制文件的目录
chdir(dirname(path));
//然后进入三个目录,进入.app包的文件夹
chdir(“../../”);

从应用程序包外部加载资源是一个安全漏洞。苹果在10.12版本中实施了应用程序移位(又称路径随机化)来防止它。他们推荐的解决方案是在签名磁盘映像中发布应用程序。见:

从macOS 10.12开始,您不能再在zip存档或未签名磁盘映像中提供代码签名应用程序旁边的外部代码或数据。在Mac app Store外部分发的应用程序在启动时以随机路径运行,因此无法访问此类外部资源。要提供安全执行,请使用codesign工具对磁盘映像本身进行代码签名,或通过Mac app Store分发应用程序。有关详细信息,请参见的更新版本


嗯。。。谢谢你提供的信息!我将尝试磁盘映像方法。对于签名的磁盘映像,是否仍然可以像上面那样拥有
Foo
目录结构?那么,磁盘映像将作为根文件夹与Foo文件夹基本相似的卷装载。它将同时包含您的应用程序及其相邻资源。用户必须同时将两者复制到本地文件系统,这很难保证。您可以使磁盘映像包含一个显式的Foo文件夹,以鼓励用户将其作为一个单元进行复制,但同样,不能保证用户会真正这样做。另一种选择是提供安装程序包,而不是磁盘映像或zip存档。它将把应用程序及其资源一起安装在Foo文件夹中,比如在/Applications下。最后,您是否考虑过将这些资源转移到应用程序包中,以避免整个问题?为什么应用程序之外的资源放在首位?该软件是模块化的(字面上说,它是一个模块化的合成器模拟器),因此用户可以将文件夹(插件)添加到/plugins目录,并随意替换图形资源。.dmg方法不起作用,因为据我所知,磁盘映像是只读的。我可以将资源移动到捆绑包中,但用户必须熟悉右键单击->显示包内容。安装程序可能是个好主意,但我必须将.app和/resources和/plugins目录的位置分开,用户必须删除…我认为默认资源应该在应用程序包中。然后,该应用程序还应该寻找用户更容易访问的地方,以获取定制。例如~/Library/applicationsupport/YourAppName/Resources。由于Finder有点隐藏~/库,所以最好在应用程序中有一个菜单或按钮来为用户打开该文件夹。如果用户需要能够删除和添加资源,那么我会让应用程序在第一次运行时将内部资源复制到用户可访问的目录中,然后仅从那里加载这些资源,这样它就可以接收用户修改。由于应用程序易位,如果设置了隔离xattr,这在10.12或更高版本上不起作用。一种可能的解决方法是假设位置为/Applications/YourAppName,并通过消息框进行投诉,如果应用未安装到该位置,则退出。