Я нахожусь в узловой среде на Mac в приложении Electron, и мне нужно:
Это было очень легко сделать в окнах. Я развожу на платформенный метод nodejs os modules, поэтому, если "Дарвину", я должен сделать что-то подобное.
Я не являюсь пользователем Mac, поэтому я мало разбираюсь в процессах на Mac.
Я могу анализировать файлы .plist
если нужно, но ковыряться в папке с предпочтениями пользователей lib, не проявил многого. Есть файлы с .psp
настройками в формате .psp
но у меня нет способа увидеть, что внутри них, и просто проверить, есть ли файл Photoshop, расположенный в папке, кажется мне неаккуратным, и мне нужно получить версию.
После некоторого исследования я столкнулся с утилитой Profiler для Mac, которая, как представляется, существует во всех операционных системах Mac.
используя модуль node
exec
я получаю все установленные приложения и некоторые подробности о каждом, которые выглядят
TextEdit:
Version: 1.13 Obtained from: Apple Last Modified: 6/29/18, 11:19 AM Kind: Intel 64-Bit (Intel): Yes Signed by: Software Signing, Apple Code Signing Certification Authority, Apple Root CA Location: /Applications/TextEdit.app
теперь мне просто нужно написать простой синтаксический анализатор для анализа результатов, которые были большими с более чем 335 приложениями в json для удобства запросов.
import { exec } from 'child_process';
let proc = exec( 'system_profiler SPApplicationsDataType -detailLevel mini' );
let results = '';
proc.stdout.on( 'data', ( data ) => { results += '${ data }'; } );
proc.on( 'close', async ( code ) =>
{
let parsed = await this.sysProfileTxtToJson( results );
} );
sysProfileTxtToJson
- мой маленький метод синтаксического анализа
теперь parsed
- это json-объект, который я запрашиваю, чтобы определить, установлен ли Photoshop, и если используется несколько версий, которые являются последней версией.
здесь используется метод синтаксического анализа, который нуждается в улучшении
sysProfileTxtToJson ( data: string )
{
return new Promise<any>( ( res ) =>
{
let stream = new Readable();
stream.push( data );
stream.push( null );
let lineReader = createInterface( stream );
let apps = { Applications: [] };
let lastEntry = '';
let appPrefix = ' ';
let appPropertyPrefix = ' ';
let lastToggle, props = false;
lineReader.on( 'line', ( line: string ) =>
{
if ( line == '' && !lastToggle )
{
props = false;
return;
}
if ( line.startsWith( appPrefix ) && !props )
{
lastEntry = line.trim().replace( ':', '' );
lastToggle = true;
let current = {};
current[ "ApplicationName" ] = lastEntry
apps.Applications.push( current );
props = true;
return;
}
if ( line.startsWith( appPropertyPrefix ) && props )
{
lastToggle = false;
let tokens = line.trim().split( ':' );
let last = apps.Applications[ apps.Applications.length - 1 ];
last[ tokens[ 0 ] ] = tokens[ 1 ].trim();
}
} );
lineReader.on( 'close', () =>
{
res( apps );
} );
} );
}
В AppleScript есть несколько функций, которые могут быть использованы для достижения вашего требования. Рассмотрите возможность osascript
команд AppleScript/ osascript
через nodejs.
Позвольте сначала взглянуть на соответствующие команды AppleScript...
Следующий фрагмент AppleScript возвращает имя той версии, в которой установлена Photoshop CS5
(например, Photoshop CS5
, Photoshop CS6
, Photoshop CC
и т.д.). Нам нужно имя, чтобы иметь возможность успешно запустить приложение.
tell application "Finder" to get displayed name of application file id "com.adobe.Photoshop"
Примечание. Снимок выше ошибок, если Photoshop не установлен, поэтому мы также можем использовать это, чтобы определить, установлено ли приложение или нет.
Следующий фрагмент получает любую версию Photoshop:
tell application "Finder" to get version of application file id "com.adobe.Photoshop"
Это возвращает длинную строку, указывающую версию. Это будет что-то вроде этого фиктивного примера:
19.0.1 (19.0.1x20180407 [20180407.r.1265 2018/04/12:00:00:00) 1990-2018 Adobe Systems Incorporated
После того, как было установлено, что PhotoShop установлен, рассмотрите возможность использования команды Bash open
для запуска приложения. Например:
open -a "Adobe Photoshop CC"
Следующий пример демонстрирует, как вышеупомянутые команды могут использоваться в узле.
Примечание. В приведенном ниже shelljs
используется shelljs
exec
для выполнения команд AppleScript/osascript. Однако вы можете использовать узлы, встроенные в child_process.execSync()
или child_process.exec()
.
const os = require('os');
const { exec } = require('shelljs');
const APP_REF = 'com.adobe.Photoshop';
const isMacOs = os.platform() === 'darwin';
/**
* Helper function to shell out various commands.
* @returns {String} The result of the cmd minus the newline character.
*/
function shellOut(cmd) {
return exec(cmd, { silent: true }).stdout.replace(/\n$/, '');
}
if (isMacOs) {
const appName = shellOut('osascript -e 'tell application "Finder" \
to get displayed name of application file id "${APP_REF}"'');
if (appName) {
const version = shellOut('osascript -e 'tell application "Finder" \
to get version of application file id "${APP_REF}"'').split(' ')[0];
console.log(version); // Log the version to console.
shellOut('open -a "${appName}"'); // Launch the application.
} else {
console.log('Photoshop is not installed');
}
}
exec('system_profiler SPApplicationsDataType -detailLevel mini')
чтобы получить список всех установленных приложений, затем написал простой синтаксический анализатор, который анализировал результаты в объектах javascript, чтобы затем можно было легко запросить полученный массив. Профилировщик возвращает версию приложения, а также путь *.app
который я могу использовать для запуска. Я ничего не знаю о applecript, но представленные решения кажутся жизнеспособным вариантом, я просто выбрал exec
как никаких дополнительных операций не требуется.