Code for self-moving app, anyone? (LetsMove)

Has anyone implemented code that moves the running app to the Applications folder, similar to what LetsMove does?

This operation may be needed for apps running on 10.12 Sierra to work around a new GateKeeper restriction (called App Translocation or Gatekeeper Path Randomization).

Intriguing…

Oh, it’s not hard. The source code is pretty short and easy to follow. It’s just a question of making the effort.

I already have a solution, using a separate helper app written in AppleScript, but it turns out that what LetsMove does is safer - Apple apparently has already implemented a fix to make the way LetsMove work in the latest 10.12 beta that didn’t work work in the first beta. So I rather rely on something that mimicks that exactly instead of rolling my own, which may more likely got broken by Apple at a whim.

Why?
I thought you also read the ‘macOS 10.12 slow app start’ thread. It is not because you did not saw the issues it wasn’t a real issue. :wink: :wink: :wink: :wink: :wink: :wink: :wink: :wink: :wink:

What thread ? :wink:

Now, I just did a quick experiment :

[code] dim myapp as FolderItem = app.ExecutableFile.parent.Parent.Parent

dim destination as FolderItem = SpecialFolder.Applications

myapp.MoveFileTo(destination)[/code]

The app is signed, and it moves very nicely to Applications. This would not fly with a sandboxed app, though. If the app was to reside on a read-only DMG, I believe it would be necessary to simply copy it.

Michel, you code won’t work if the app runs translocated, which happens with codesigned apps stored in a zip file and downloaded with Safari.
If you want to know why, read https://github.com/potionfactory/LetsMove/issues/56

But that’s not really the point of this thread. We have a 280+ thread for that already :slight_smile:

Not necessarily. Where it executes has nothing to do with moving files. It runs in memory, actually, which enables moving the entire bundle as any other file, since OS X does not lock it.

Yeah, good luck with that assumption, Michel :slight_smile:

I don’t necessarily assume.

Let me understand :

  • You place the bundle into a zip file
  • Upload it to the Internet
  • Download it through Safari to Sierra
  • Extract it
  • Run it right inside the folder where it was extracted.

Is that a correct description or is there something else ? If so, I can try in a few minutes. Proof is in the pudding, without trying, we’ll never know.

Well, since I never leave any stone unturned, I compressed my test app signed with App Wrapper and placed it on my server, at
http://fontmenu.com/xojo/moving.app.zip

Downloaded it through Safari within macOS, opened it right in the spring menu from Downloads in the dock, and guess what ? It actually copied itself into Applications. It runs very nicely from Applications.

Should be noted that it took only about five seconds to open from the download. And only 3-4 when in the Applications folder (I tend to count the bounces).

We did this in the past, ended up using AppleScript (within the application).

It gets the Finder to copy the application there; launches it from the new location and then gets the Finder to move the original app to trash and quits.

It had to be done as we ran into problems when moving a live application and APIs would fail if the user has to authenticate to access the apps folder.

With Sandboxing, it can’t be done. We do use an Apple Script as an installer on the DMG however.

Okay, Michel, you’re right. I was wrong because I incorrectly assumed that Xojo’s Move command would only move - but it does apparently revert to Copy if the Move fails. Because that’s the issue - A translocated app can’t move itself because the temp folder in which is resides it read-only.

In a way, though, your solution is not complete, because you leave the original version in the Downloads folder, which should not happen - it should be cleared. But again, that you cannot do with your approach because you are not able to find your original app because you cannot get the original path from where it was launched. So, if I’d download to a different folder or if it would get renamed when extracting, you’d not be able to find that original when the app runs translocated. That’s the basis of this thread - to implement a solution that does this right.

Since the app itself detects where it resides with App.ExecutableFile, I frankly fail to see what would be the problem.

I have the feeling you may be overthinking it.

Michel, which path do you think you get when you call App.ExecutableFile when your app runs for the first time, right after unzipping, e.g. from the /Users/you/Downloads folder? You do realize it’s not /Users/you/Downloads/Your.app, right?

Here is the path of App.Executablefile :

/private/var/folders/9s/10t5q2h939d_b9ptbff4vfy00000gn/T/AppTranslocation/988E22D6\\-A5FE\\-4636\\-B5E7\\-8B63CD089970/d/moving.app/Contents/MacOS/moving

So indeed the app is translocated, but yet, Xojo copies perfectly to Applications.

Of course it will not be possible to delete the bundle in Downloads since all the app sees is its own container. I look forward to see a solution that does.

So, for the record:

It’s taken me a few hours, but I’ve got now a working Xojo version of what “LetsMove” (https://github.com/potionfactory/LetsMove) does, along with handling the cases where the Apps folder is not writable and an Admin login is required. It also manages to remove the source app from the Download folder, even on 10.12 Sierra.

The only thing it doesn’t do is to specially handle apps started from a dmg volume, i.e. it does not unmount and trash the dmg after the successful move. Meaning that this code is mainly made for apps delivered as .zip files, solving issues we’ll encounter on Sierra due to apps runnning translocated when started from the Downloads folder.

A slightly commented version of the project is here: http://files.tempel.org/RB/MoveMe%20Xojo%20Source.zip

Enjoy.