@@ -49,6 +49,7 @@ + (NSBundle *)bundle {
4949static BOOL MoveInProgress = NO ;
5050
5151// Helper functions
52+ static NSURL * GetOriginalBundleURL (void );
5253static NSString *PreferredInstallLocation (BOOL *isUserDirectory);
5354static BOOL IsInApplicationsFolder (NSString *path);
5455static BOOL IsInDownloadsFolder (NSString *path);
@@ -78,7 +79,7 @@ void PFMoveToApplicationsFolderIfNecessary(void) {
7879 if ([[NSUserDefaults standardUserDefaults ] boolForKey: AlertSuppressKey]) return ;
7980
8081 // Path of the bundle
81- NSString *bundlePath = [[ NSBundle mainBundle ] bundlePath ] ;
82+ NSString *bundlePath = GetOriginalBundleURL (). path ;
8283
8384 // Check if the bundle is embedded in another application
8485 BOOL isNestedApplication = IsApplicationAtPathNested (bundlePath);
@@ -239,6 +240,56 @@ BOOL PFMoveIsInProgress() {
239240#pragma mark -
240241#pragma mark Helper Functions
241242
243+ // / Gets the real bundle path of the application, not the Translocated one if applicable
244+ static NSURL * GetOriginalBundleURL (void ) {
245+
246+ NSURL * bundleURL = [NSBundle mainBundle ].bundleURL ;
247+ NSLog (@" %s : Foundation says bundle URL is %@ " , __FUNCTION__, bundleURL);
248+
249+ // #define NSAppKitVersionNumber10_11 1404
250+ if (floor (NSAppKitVersionNumber ) <= 1404 ) {
251+ return bundleURL;
252+ }
253+
254+ void * handle = dlopen (" /System/Library/Frameworks/Security.framework/Security" , RTLD_LAZY);
255+ if (handle == NULL ) {
256+ return bundleURL;
257+ }
258+
259+ bool isTranslocated = false ;
260+
261+ // Get (undocumented?) function symbols for looking up app translocation info
262+ // Note: <Security/SecTranslocation.h> was available in the macOS 10.12 beta SDKs but seems to have been removed as of Xcode 8.1
263+ // see https://opensource.apple.com/source/Security/Security-58286.70.7/OSX/libsecurity_translocate/lib/SecTranslocate.h.auto.html
264+
265+ typedef Boolean (*SecTranslocateIsTranslocatedURL_t)(CFURLRef path, bool *isTranslocated, CFErrorRef * __nullable error);
266+ SecTranslocateIsTranslocatedURL_t mySecTranslocateIsTranslocatedURL = (SecTranslocateIsTranslocatedURL_t)dlsym (handle, " SecTranslocateIsTranslocatedURL" );
267+
268+ typedef CFURLRef __nullable (*SecTranslocateCreateOriginalPathForURL_t)(CFURLRef translocatedPath, CFErrorRef * __nullable error);
269+ SecTranslocateCreateOriginalPathForURL_t mySecTranslocateCreateOriginalPathForURL = (SecTranslocateCreateOriginalPathForURL_t)dlsym (handle, " SecTranslocateCreateOriginalPathForURL" );
270+
271+ dlclose (handle);
272+
273+ if (mySecTranslocateIsTranslocatedURL == NULL || mySecTranslocateCreateOriginalPathForURL == NULL ) {
274+ NSLog (@" %s : We're running on macOS >= 10.12 but the SecTranslocate functions are not available" , __FUNCTION__);
275+ return bundleURL;
276+ }
277+
278+ if (mySecTranslocateIsTranslocatedURL ((__bridge CFURLRef)bundleURL, &isTranslocated, NULL ) && isTranslocated)
279+ {
280+ CFURLRef originalURL = mySecTranslocateCreateOriginalPathForURL ((__bridge CFURLRef)bundleURL, NULL );
281+ if (originalURL != NULL )
282+ {
283+ NSURL * result = CFBridgingRelease (originalURL);
284+ NSLog (@" %s : Security says bundle is Translocated from %@ " , __FUNCTION__, result);
285+ return result;
286+ }
287+ }
288+
289+ NSLog (@" %s : Translocation not in effect" , __FUNCTION__);
290+ return bundleURL;
291+ }
292+
242293static NSString *PreferredInstallLocation (BOOL *isUserDirectory) {
243294 // Return the preferred install location.
244295 // Assume that if the user has a ~/Applications folder, they'd prefer their
0 commit comments