Принудительный программный запуск приложения Cocoa в 32-битном режиме

У меня есть приложение Cocoa, которое обычно работает в полном 64-битном режиме на любом Mac, поддерживающем эту архитектуру.

Теперь у меня есть внешний API, который доступен только в виде 32-битного плагина для загрузки в основную программу. Этот API предназначен для стороннего устройства ввода, которое когда-либо купит лишь небольшой процент моих пользователей, но это важно для этого небольшого процента.

Моя проблема в том, что программа может использовать этот API только в том случае, если она выполняется в 32-битном режиме. Конечно, проще всего:

Сценарий 1: попросите пользователя запустить программу в 32-разрядном режиме, изменив ее информацию в диалоговом окне "Получить информацию" Finder.

Это легко сделать, но вряд ли элегантно.

Сценарий 2: всегда запускайте в 32-разрядном режиме, чтобы избежать проблемы

Вряд ли то, что я хочу сделать.. Наказание 98% пользователей ради экзотической функции.

Сценарий 3. Автоматически измените атрибуты запуска приложения, чтобы оно запускалось в 32-разрядном режиме при следующем запуске и каждый раз после этого

or

Сценарий 4. Во время запуска определите, какая архитектура используется, затем при необходимости перезапустите в 32-разрядном режиме

Сценарии 3 и 4 имеют проблему, заключающуюся в том, что очень мало документировано о том, как это сделать, и это может привести к проблемам с рекомендациями Mac App Store.

На данный момент я установил:

Пока я вижу только эти варианты, ни один из которых не кажется особенно хорошим:

  1. перезапустите приложение с помощью NSTask и инструмента командной строки «arch»
  2. писать прямо в com.apple.LaunchServices.plist
  3. изолировать 32-битный плагин в его собственном 32-битном процессе и использовать IPC

Решение 1 может вызвать у меня проблемы с отправкой MAS. Решение 2 почти наверняка сделает это на каком-то этапе... только решение 3 будет идеальным с точки зрения пользователя, но добавит огромную сложность для минимальной отдачи.

Любые советы о том, как сделать это «чисто» и с разумными усилиями, будут высоко оценены!


person Frank    schedule 15.08.2011    source источник
comment
Почему это имеет значение, если ваше приложение только 32-разрядное - ему требуется большой объем памяти (> 2 ГБ)?   -  person Paul R    schedule 15.08.2011
comment
Является ли работа всегда в 32-битном режиме таким большим штрафом?   -  person hamstergene    schedule 15.08.2011
comment
возможный дубликат Как программно запустить программу в 32-битной или 64-битной среде?   -  person ughoavgfhw    schedule 15.08.2011
comment
Приложение использует сборку мусора, которая работает намного лучше в 64-битном режиме, так что да, это большой штраф для ВСЕХ пользователей. Это похоже на другой связанный вопрос, но и на него нет удовлетворительного ответа.   -  person Frank R.    schedule 16.08.2011


Ответы (4)


Вариант 5: Создайте еще один исполняемый файл, который всегда работает как 32-разрядный, и его единственной целью является управление рассматриваемым 32-разрядным компонентом. Запустите этот исполняемый файл из вашего основного приложения и используйте какой-либо независимый от процессора ввод-вывод для связи друг с другом, возможно, через сокеты.

person justin.m.chase    schedule 16.08.2011

Я понял, как установить ключ, используя значения по умолчанию...

Учитывая переменную оболочки bash:

alias="<0000 .... 1234>"  #(there is a lot more hex data than that...)

И идентификатор пакета:

bundle="com.mycompany.myprogram"

Вы можете установить ключ таким образом:

defaults write com.apple.LaunchServices LSArchitecturesForX86_64 -dict-add $bundle "($alias, i386)"

Удачи в создании бинарного псевдонима. Я просто украл _CFURLAliasData из com.plist.dock, так как программа, которую я пытаюсь настроить для запуска 32-битной версии, имеет значок, установленный в доке. Другой способ сгенерировать псевдоним, если вы можете его достать, может заключаться в использовании программы dokit.c. Я не смог найти эту программу.

person John Wolf    schedule 17.03.2012
comment
Будет ли переменная псевдонима клавишей 0 под идентификатором пакета, если я посмотрю в plisteditor pro? Я думаю, что это может быть. Во всяком случае, я думаю, что здесь замешан какой-то кеш. Если я использую описанный выше подход Bash, состояние флажка информационного диалогового окна не показывает, что оно изменилось, ЕСЛИ Я не принудительно выйду из Finder. Он должен запускать что-то, что перестраивает его внутреннее кэширование. Глядя сюда, кажется, что thexlab.com/faqs/resetlaunchservices.html - person Keegan 82; 25.02.2014
comment
Даже при принудительном выходе я обнаружил, что приложение, в частности, реагирует только на тики диалогового окна с информацией вручную. Другими словами, даже если я запускаю сценарий bash, чтобы сказать 32-битный, и вижу, что он изменился в поле флажка пользовательского интерфейса, мое приложение по-прежнему запускается в 64-битном режиме. Сейчас я попробую просто создать 2 копии пакета .app. - person Keegan 82; 25.02.2014

Вы можете программно изменить режим запуска вашего приложения, изменив файл plist, расположенный здесь:

~/Library/Preferences/com.apple.LaunchServices.plist

Вам нужно изменить ключ, расположенный в /LSArchitecturesForX86_64/[your.app.idenitfier]/Item 1/

  • установка его на x86_64 будет работать в 64-битной версии
  • установка его на i386 будет работать в 32-битном режиме

Вы можете редактировать это с помощью встроенной команды defaults или встроенной команды plistbuddy. Мне никогда не удавалось получить ключ, который может понижать уровень, чтобы измениться с помощью defaults, если я выясню синтаксис plistbuddy, я опубликую его.

Когда у вас все это есть, вы можете создать простой скрипт для запуска при входе в систему, который проверяет наличие вашего устройства ввода (или другого атрибута, отдела и т. д.) и соответствующим образом устанавливает режим запуска.

person Don    schedule 03.10.2011

Мой сценарий очень похож. Я использую Ableton Live и Reason в качестве ведомого устройства. Если я запускаю Ableton в 32-битном режиме, мне нужно, чтобы Reason был в 32-битном режиме. Вот что я сделал.

  1. Сделайте копию приложения, с помощью которого вы хотите быстро менять режимы.
  2. Назовите копию 32.app (в моем случае Reason32.app)
  3. Показать содержимое пакета этого нового приложения и удалить папку «Содержание» (да, ту, которая содержит все)
  4. Теперь заходим в оригинал, делаем симлинк Contents
  5. Скопируйте символическую ссылку в пакет appname32.app (там, где раньше находился старый удаленный)
  6. Используйте свойства Finder и отметьте 32-битный режим для вашей новой копии.

Теперь у вас есть 2 приложения, которые вы можете легко запустить/скриптовать.

person Keegan 82    schedule 25.02.2014