{"id":42,"date":"2005-07-12T11:33:03","date_gmt":"2005-07-12T15:33:03","guid":{"rendered":"http:\/\/benjamin.smedbergs.us\/blog\/?p=42"},"modified":"2005-07-12T12:24:06","modified_gmt":"2005-07-12T16:24:06","slug":"thank-you-macdev","status":"publish","type":"post","link":"http:\/\/benjamin.smedbergs.us\/blog\/2005-07-12\/thank-you-macdev\/","title":{"rendered":"Thank you #macdev!"},"content":{"rendered":"<p>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&#8217;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&#8217;t working&#8230; 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).<\/p>\n<p>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.<\/p>\n<style type=\"text\/css\">.irclog {  font-family: monospace;  font-size: 85%;} .irclog p {border-bottom: 2px solid #D8D8CE; margin: 0px; padding: 1px; } <\/style>\n<div class=\"irclog\">\n<p>&lt;bsmedberg&gt; Is this a decent place to ask questions about application bundles and launch services?<\/p>\n<p>&lt;mikeash&gt; I wouldn&#8217;t call it decent, &#8220;wretched hive of scum and villainy&#8221; is more appropriate<\/p>\n<p>[snip]<\/p>\n<p>&lt;bsmedberg&gt; Is there some way to run \/foo\/bar-executable but tell launch services to pretend that it&#8217;s running as part of \/bar\/MyApp.app ?<\/p>\n<p>&lt;mikeash&gt; &#8220;as part of&#8221;?<\/p>\n<p>&lt;bsmedberg&gt; Basically, I want to stick a &#8220;runtime executable&#8221; in \/Library\/XUL.framework\/Versions\/&lt;foo&gt;\/xulrunner-bin<\/p>\n<p>&lt;bsmedberg&gt; sorry, \/Library\/Frameworks\/&#8230;<\/p>\n<p>&lt;arwyn&gt; 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?<\/p>\n<p>&lt;bsmedberg&gt; And when a user runs \/bar\/XULApplication.app it will have a little stub binary at Contents\/MacOS\/xulrunner-stub<\/p>\n<p>* arwyn suggests a symlink<\/p>\n<p>&lt;mikeash&gt; that sure sounds like odd design<\/p>\n<p>&lt;mikeash&gt; I *think* that if your app&#8217;s main executable just execs the other one, it&#8217;ll work, but I&#8217;ve never tried it and I&#8217;m nowhere near sure<\/p>\n<p>&lt;bsmedberg&gt; it doesn&#8217;t work to execv the other one :-(<\/p>\n<p>&lt;arwyn&gt; what doesn&#8217;t work?<\/p>\n<p>&lt;bsmedberg&gt; the xulrunner-bin doesn&#8217;t get menus\/dock icon (can&#8217;t activate the window)<\/p>\n<p>&lt;arwyn&gt; and to be clear, we are talking about exec() the system call&#8230; not relaunching via LS<\/p>\n<p>&lt;bsmedberg&gt; correct<\/p>\n<p>&lt;mikeash&gt; does xulrunner-bin work properly when it&#8217;s actually the main executable of your app?<\/p>\n<p>&lt;bsmedberg&gt;yes<\/p>\n<p>&lt;arwyn&gt; 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?<\/p>\n<p>&lt;bsmedberg&gt; as long as all the rest of the XUL framework is along with it<\/p>\n<p>&lt;bsmedberg&gt; arwyn: no, I didn&#8217;t&#8230; does the OS use the argv[0] to determine the bundle?<\/p>\n<p>* bsmedberg gets excited<\/p>\n<p>&lt;arwyn&gt; yes, there is no other way<\/p>\n<p>&lt;bsmedberg&gt; cool, I&#8217;ll try that, thanks<\/p>\n<p>&lt;mikeash&gt; arwyn, aren&#8217;t there undocumented ways, like env(&#8220;_&#8221;) or something?<\/p>\n<p>&lt;arwyn&gt; I know this type of re-exec() trick can work, people on this channel have done it<\/p>\n<p>&lt;arwyn&gt; it might just need some tweaking<\/p>\n<p>&lt;mikeash&gt; I think that Firefox does it<\/p>\n<p>&lt;bsmedberg&gt; well, no<\/p>\n<p>&lt;bsmedberg&gt; Firefox execs itself, but it&#8217;s the same binary<\/p>\n<p>* bsmedberg wrote that code<\/p>\n<p>&lt;arwyn&gt; heh<\/p>\n<p>&lt;mikeash&gt; I don&#8217;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<\/p>\n<p>&lt;arwyn&gt; mike, maybe&#8230; I&#8217;m not entirely sure<\/p>\n<p>&lt;arwyn&gt; binary doesn&#8217;t matter at all, its all paths &#038; args<\/p>\n<p>&lt;mikeash&gt; arwyn, anyway, irrelevant since Apple does apparently use argv[0]<\/p>\n<p>&lt;arwyn&gt; argv is accessible via the NSGetArgv() stuff in Libc, which is what CF\/NS uses to get it later to do main bundling<\/p>\n<p>&lt;mikeash&gt; I can&#8217;t even think of a way that LS could even detect that you&#8217;ve re-exec&#8217;d, much less figure out whether you re-exec&#8217;d the same binary or a different one<\/p>\n<p>[snip a long discussion that I didn&#8217;t understand about how the Mac OS could do this differently if it really wanted to]\n<\/p><\/div>\n<p>Thank you <a href=\"http:\/\/www.mikeash.com\/\">Mike Ash<\/a> and arwyn (whose real name I don&#8217;t know) for your invaluable help! I would probably be rearchitechting how mac bundles launched the XULRunner if it weren&#8217;t for you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was stuck in a hole yesterday trying to break free, and then I visited freenode #macdev&#8230; thank you to &#8216;arwyn&#8217; (real name unknown) and <a href=\"http:\/\/www.mikeash.com\/\">mikeash<\/a> for their invaluable assistance!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-42","post","type-post","status-publish","format-standard","hentry","category-mozilla"],"_links":{"self":[{"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/posts\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/comments?post=42"}],"version-history":[{"count":0,"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/posts\/42\/revisions"}],"wp:attachment":[{"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/media?parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/categories?post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/benjamin.smedbergs.us\/blog\/wp-json\/wp\/v2\/tags?post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}