问题
I have a Cocoa application that usually runs in full 64-bit mode on any Mac that supports this architecture.
Now I have an external API that is only available as a 32-bit plug-in to be loaded into the main program. This API is for a third-party input device that only a small percentage of my users will ever purchase, but that is important for that small percentage.
My problem is that the program can only use this API if executed in 32-bit mode. The easiest thing to do is of course to:
Scenario 1: ask the user to start the program in 32-bit mode by changing its information via the Finder's Get Info dialog.
This is easily done, but hardly elegant..
Scenario 2: always run in 32-bit mode thus avoiding the problem
Hardly what I want to do either.. penalizing 98% of users for the sake of an exotic feature.
Scenario 3: automatically change the application's launch attributes so that it starts in 32-bit mode next time it is launched and every time afterwards
or
Scenario 4: at launch time, establish which architecture is being used, then re-launch in 32-bit mode if necessary
Scenarios 3 & 4 have the problem that very little is documented on how to do this and it might get me into trouble with the Mac App Store guidelines.
So far, I've established:
- that using the "arch" command line tool will allow me to restart my executable in 32-bit mode
- Finder scripting won't let me change the "Launch in 32-bit mode" flag
- the flag is managed by the Launch Services API (http://blog.timac.org/?p=490)
- BUT I haven't found any interface to programmatically change the flag in the Launch Services API
So far I can see only these options, none of which seem particularly great:
- relaunch the application using NSTask and the "arch" command line tool
- write directly into the com.apple.LaunchServices.plist
- isolate the 32-bit plug-in into its own 32-bit only process and use IPC
Solution 1 could get me into trouble with the MAS submission. Solution 2 would almost certainly do so at some stage.. only solution 3 would be perfect from a user's perspective but add a huge amount of complexity for minimal pay-off.
Any advice on how to do this "cleanly" and with reasonable effort would be highly appreciated!
回答1:
Option 5: Create another executable that always runs as 32 bit and its sole purpose is to drive the 32 bit component in question. Launch that executable from your primary application and use some type of processor independent io to communicate with each other, probably sockets.
回答2:
I figured out the way to set the key using defaults...
Given a bash shell variable:
alias="<0000 .... 1234>" #(there is a lot more hex data than that...)
And the bundle identifier:
bundle="com.mycompany.myprogram"
You can set the key thusly:
defaults write com.apple.LaunchServices LSArchitecturesForX86_64 -dict-add $bundle "($alias, i386)"
Good luck generating the binary alias. I just steal the _CFURLAliasData from com.plist.dock since the program I am trying to set to launch 32bit has an icon installed into the dock. The other way to generate the alias, if you can get your hands on it, might be to use the program dockit.c. I haven't been able to find that program.
回答3:
You can programmatically change what mode your application will launch in by changing the plist file located here:
~/Library/Preferences/com.apple.LaunchServices.plist
You need to change the key located at
/LSArchitecturesForX86_64/[your.app.idenitfier]/Item 1/
- setting it to
x86_64
will run in 64 bit - setting it to
i386
will run in 32 bit
You can edit this with either the built in defaults
command or the built in plistbuddy
command. I have never had much luck getting a key that may levels down to change with defaults
, if I figure out the plistbuddy
syntax I will post it.
Once you have all that, you can create a simple script to run at log in that tests for the presence of your input device (or a another attribute, department etc) and sets the launch mode accordingly.
回答4:
My scenario is very similar. I use Ableton Live and Reason as a rewire slave. If I launch Ableton in 32bit I need Reason to be in 32bit mode. Here's what I did.
- Make a copy of the app you want to be able to change modes quickly with.
- Call the copy 32.app (in my case Reason32.app)
- Show package contents of this new app and delete the Contents folder (Yes the one that contains everything)
- Now go into the original, make a symlink of Contents
- Copy symlink into the appname32.app package (where old deleted one used to reside)
- Use the finder properties and tick 32bit mode for your new copy.
You now have 2 apps you can easily launch/script.
来源:https://stackoverflow.com/questions/7064450/forcing-a-cocoa-application-to-start-in-32-bit-mode-programatically