Thank you #macdev!

I was stuck in a funk yesterday, trying to get XULRunner application bundles working properly on Mac OS X. The basic problem is that I’m trying to run the xulrunner-bin executable from the XUL.framework, but have the launch manager think that it is running as the application bundle (using the application bundle dock icon/application name/etc). The basic strategy is to have a little stub binary inside the application bundle which will execv to the xulrunner-bin binary. However, this wasn’t working… Launch Services was convinced that the xulrunner-bin was running on its own, and because it is part of a framework instead of an application bundle, it was running as a background application (no access to the dock or menus).

In my frustration I visited my infrequent hangout freenode #opendarwin, who were quick to inform me that launch services was not their domain, but that I should visit #macdev.

<bsmedberg> Is this a decent place to ask questions about application bundles and launch services?

<mikeash> I wouldn’t call it decent, “wretched hive of scum and villainy” is more appropriate


<bsmedberg> Is there some way to run /foo/bar-executable but tell launch services to pretend that it’s running as part of /bar/ ?

<mikeash> “as part of”?

<bsmedberg> Basically, I want to stick a “runtime executable” in /Library/XUL.framework/Versions/<foo>/xulrunner-bin

<bsmedberg> sorry, /Library/Frameworks/…

<arwyn> so you want to have your normal app bundle in /bar/MyApp, but you want the actual executable file to be from /Library/XUL.framework,e tc?

<bsmedberg> And when a user runs /bar/ it will have a little stub binary at Contents/MacOS/xulrunner-stub

* arwyn suggests a symlink

<mikeash> that sure sounds like odd design

<mikeash> I *think* that if your app’s main executable just execs the other one, it’ll work, but I’ve never tried it and I’m nowhere near sure

<bsmedberg> it doesn’t work to execv the other one :-(

<arwyn> what doesn’t work?

<bsmedberg> the xulrunner-bin doesn’t get menus/dock icon (can’t activate the window)

<arwyn> and to be clear, we are talking about exec() the system call… not relaunching via LS

<bsmedberg> correct

<mikeash> does xulrunner-bin work properly when it’s actually the main executable of your app?


<arwyn> in your exec(), did you preserve the original argv[] parameters so that the OS will think the bundle is still located in the right place?

<bsmedberg> as long as all the rest of the XUL framework is along with it

<bsmedberg> arwyn: no, I didn’t… does the OS use the argv[0] to determine the bundle?

* bsmedberg gets excited

<arwyn> yes, there is no other way

<bsmedberg> cool, I’ll try that, thanks

<mikeash> arwyn, aren’t there undocumented ways, like env(“_”) or something?

<arwyn> I know this type of re-exec() trick can work, people on this channel have done it

<arwyn> it might just need some tweaking

<mikeash> I think that Firefox does it

<bsmedberg> well, no

<bsmedberg> Firefox execs itself, but it’s the same binary

* bsmedberg wrote that code

<arwyn> heh

<mikeash> I don’t think that being the same binary is going to magically make it work, and being a different binary is going to magically make it break

<arwyn> mike, maybe… I’m not entirely sure

<arwyn> binary doesn’t matter at all, its all paths & args

<mikeash> arwyn, anyway, irrelevant since Apple does apparently use argv[0]

<arwyn> argv is accessible via the NSGetArgv() stuff in Libc, which is what CF/NS uses to get it later to do main bundling

<mikeash> I can’t even think of a way that LS could even detect that you’ve re-exec’d, much less figure out whether you re-exec’d the same binary or a different one

[snip a long discussion that I didn’t understand about how the Mac OS could do this differently if it really wanted to]

Thank you Mike Ash and arwyn (whose real name I don’t know) for your invaluable help! I would probably be rearchitechting how mac bundles launched the XULRunner if it weren’t for you.

Atom Feed for Comments 2 Responses to “Thank you #macdev!”

  1. David Says:

    So how did this work out in the end? I’m in a similar predicament trying to get an XUL app I wrote and used in Windows and Linux to run properly in OS X. It pops up but only some of the buttons work (and only when you click on it on one side and drag the pointer over) and the actual window is in the background that sounds like your problem.

    Is there an example somewhere with everything in the proper structure to pop the app-specific data into?

    There’s not much online about these errors, but I do know that it ran clean on other platforms. debug.log:

    Test App (1.0)
    error including file: ‘chrome://testapp/content/constants.js’, [Exception… “Component returned failure code: 0x80570018 (NS_ERROR_XPC_BAD_IID) [nsIJSCID.getService]” nsresult: “0x80570018 (NS_ERROR_XPC_BAD_IID)” location: “JS frame :: chrome://testapp/content/constants.js :: :: line 106” data: no]

    Error: [JavaScript Error: “uncaught exception: [Exception… “Component returned failure code: 0x80570018 (NS_ERROR_XPC_BAD_IID) [nsIJSCID.getService]” nsresult: “0x80570018 (NS_ERROR_XPC_BAD_IID)” location: “JS frame :: chrome://testapp/content/constants.js :: :: line 106″ data: no]”]

    Error: [JavaScript Error: “hrCommands is not defined” {file: “chrome://testapp/content/testapp.xul” line: 381}]
    File: chrome://testapp/content/testapp.xul (381)

    error including file: ‘chrome://testapp/content/constants.js’, [Exception… “Component returned failure code: 0x80570018 (NS_ERROR_XPC_BAD_IID) [nsIJSCID.getService]” nsresult: “0x80570018 (NS_ERROR_XPC_BAD_IID)” location: “JS frame :: chrome://testapp/content/constants.js :: :: line 106” data: no]

  2. Benjamin Smedberg Says:

    David, please see

Leave a Reply