How to copy a helper app to the Application Support folder?

Because of MAS requirements, I need to copy a helper app from my app bundle to the Application Support folder, before my app can use it.
It works in debug mode, but not when I build the app.
What I did is to add a Build Step / Copy Files / App Parent to my Xojo project.
When I build the app, it’s then part of the application package, it sits next to the app in Contents/MacOS.
I want to copy it to the Application Support folder during the app’s first run.
This is my code:

The folder is created, but the file doesn’t copy to the folder
It doesn’t seem to find the source file when in the bundle
I’ve also tried this: g = g.Child(“MyFile/Contents/MacOS”)

Ideas, anyone?

Don’t use Copy Files and also don’t use CopyFileTo. Copy Files loves to lose the files it is supposed to copy. Use the shell command “ditto” for both.

Why would you need to run an app from the Application Support folder? Helper apps should be run from Contents/Library/Helpers.

You may not be able to copy from the macOS folder. Try putting the helper in the Resources directory instead.


@Greg Same problem, source file is not found. I tried g = g.Child(“Contents/Resources/MyFile”)
How do I reference a file inside the Resources folder of the bundle?

@Beatrix I can’t use a shell command, it’s not allowed in the MAS.

There is no Contents/Library/Helpers in my bundle? Or are you referring to some sort of hidden folder on the disk?

You can use the shell in your own IDE script. Here is my script to copy a helper into the main app:

[code]'copy the scheduler to app/library/loginitems

dim appPath as string = currentBuildLocation + “/” + shellEncode(currentBuildAppName)
if right(AppPath, 4) <> “.app” then appPath = appPath + “.app”

'do directory for loginitems
dim cmd as String = "/bin/mkdir -p " + appPath + “/Contents/Library/LoginItems”
dim theOutput as string = doShellCommand(cmd)
if theOutput <> “” then print theOutput

'get path to scheduler
dim CountSlashes as integer = CountFields(ProjectShellPath, “/”)
dim ProjectName as string = NthField(ProjectShellPath, “/”, CountSlashes)
dim ProjectPath as String = Left(ProjectShellPath, Len(ProjectShellPath) - Len(ProjectName))
dim PathToScheduler64 as String = ProjectPath + shellEncode(“Builds - max scheduler.rbp/OS X 64 bit”)

'copy scheduler to app for 64bit
cmd = "usr/bin/ditto " + PathToScheduler64 + " " + appPath + “/Contents/Library/LoginItems”
'print "cmd " + cmd
theOutput = doShellCommand(cmd)
if theOutput <> “” and instr(theOutput, “can’t get real path”) = 0 then print theOutput

// Helper functions for this script
Function shellEncode(inValue as string) as string
Dim rvalue as string = replaceAll(inValue, " ", "\ ")
rvalue = replaceAll(rvalue, “&”, “\&”)
rvalue = replaceAll(rvalue, “-”, “\-”)
rvalue = replaceAll(rvalue, “(”, “\(”)
rvalue = replaceAll(rvalue, “)”, “\)”)
return rvalue
End Function[/code]

Anything else besides “ditto” gives problems with permissions. Been there, done that: have had much fun.

AFAIR there is a replacement (MBS???) so that you can use the shell for MAS. But honestly, you only need something like the script above.

[quote=418287:@Vincent Verweij]
How do I reference a file inside the Resources folder of the bundle? [/quote]
Use SpecialFolder

[quote=418287:@Vincent Verweij]@Beatrix I can’t use a shell command, it’s not allowed in the MAS.

Helper apps should be run from Contents/Library/Helpers[/quote]

You have to use NSTask. There’s an implementation in my Sandbox Kit or (almost certain) there’s one in the MBS plugin.

The biggest problem with a Sandboxed helper is file access, it doesn’t have the same rights to files as your main application. It can only access a few folders on the system (namely the app support folder). In order to get the helper to open files that your main application needs, you have to create a in-secure Bookmark and use IPC to send that bookmark to the helper (I only just discovered this myself this year, I’ve been moving the users files around for a while now).

Technically the limitation is not MAS, its the App Sandbox; (the rules overlap, but it’s important to know which one is which as I suspect one day, the App Sandbox will be enforced outside of the App Store.

To use helpers within a Sandboxed application, they must be code signed along with the main application (App Wrapper can help with this). Once they’re code signed and also Sandboxed, they cannot be called from the Terminal or Shell. Apple won’t accept the app on the App Store with the helper unsigned. So it doesn’t matter if you copy the helper elsewhere (and in doing so, Apple might think you’re trying to be naughty).

My honest suggestion to you is to reconsider why you need a helper application in the first place, with the App Sandbox restrictions, it makes this process quite an upheaval just to get started.

Okay, so I’ve just seen your e-mails, I’m sorry for not responding sooner.

In your case, you’re not going to be able to modify the helper, so what you’ll have to do is the following.

Include your helper application in the “Helpers” or “MacOS” folder within your application. In code you can use OWShell class, make sure you pass True to it at creation time to use NSTask underneath.

Move the file you want to process to the application support folder (Moving is a lot quicker than copying), then process it from there. Don’t forget to move it back when you’re done.

You can use “app.executableFile.parent” to get to the “MacOS” folder within your application, if you include your Helper in that folder.

@Vincent Verweij — There are many folders that you can create in your application bundle and Library/Helpers is one of them (it does not exist by default).

Also, just to make sure, have you properly typed your app extension in the path? It has to be “”

Thanks for all the help and suggestions. I’ll be trying those in the coming days.