ohmu
·
2026-10-15
1#include "common/apple/version.h"
2#include "common/strutil.h"
3
4#import <Foundation/Foundation.h>
5
6#define APP_CONTENTS_MACOS ".app/Contents/MacOS"
7
8bool ffGetAppNameAndVersion(const char* exePath, FFstrbuf* retName, FFstrbuf* retVersion) {
9 char* lastSlash = strrchr(exePath, '/');
10 if (!lastSlash) {
11 return false;
12 }
13 if ((size_t) (lastSlash - exePath) > strlen("X" APP_CONTENTS_MACOS) && memcmp(lastSlash - strlen(APP_CONTENTS_MACOS), APP_CONTENTS_MACOS, strlen(APP_CONTENTS_MACOS)) != 0) {
14 return false;
15 }
16
17 lastSlash -= strlen("MacOS");
18 char infoPlistPath[PATH_MAX];
19 memcpy(infoPlistPath, exePath, (size_t) (lastSlash - exePath));
20 memcpy(infoPlistPath + (lastSlash - exePath), "Info.plist", sizeof("Info.plist")); // X.app/Contents/Info.plist
21 NSError* error;
22 NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@(infoPlistPath)]
23 error:&error];
24 if (!dict) {
25 return false;
26 }
27
28 if (retName) {
29 NSString* bundleName = dict[@"CFBundleDisplayName"] ?: dict[@"CFBundleName"];
30 if (bundleName) {
31 ffStrbufSetS(retName, bundleName.UTF8String);
32 }
33 }
34
35 if (retVersion) {
36 NSString* bundleVersion = dict[@"CFBundleShortVersionString"];
37 if (bundleVersion) {
38 ffStrbufSetS(retVersion, bundleVersion.UTF8String);
39 }
40 }
41
42 return true;
43}