简体   繁体   English

确定Node.js JavaScript中是否已安装软件以及Mac上的版本

[英]Determine if software is installed and what version on Mac in Node.js JavaScript

I am in a node environment on Mac within a Electron application and I am needing to: 我在一个Electron应用程序中的Mac上的节点环境中,我需要:

  1. test if Photoshop is installed 测试是否已安装Photoshop
  2. get version of installed Photoshop 获取安装的Photoshop版本
  3. launch Photoshop 启动Photoshop

This was all extremely easy to do in windows. 在Windows中这一切都非常容易做到。 I branch on nodejs os modules platform method so if 'Darwin' I need to do the above things. 我在nodejs操作系统模块平台方法上进行了分支,因此如果使用“达尔文”,则需要执行上述操作。

I am not a Mac user so I do not know much about the processes on Mac. 我不是Mac用户,所以我对Mac上的进程了解不多。

I can parse .plist files if need be but poking around users lib preference folder hasn't showed up much. 如果需要的话,我可以解析.plist文件,但在用户lib首选项文件夹中戳不出来。 There are Photoshop specific .psp preference files but I have no way to see whats inside them and merely checking to see if there is a Photoshop file located in folder seems way to sloppy to me plus I need to get the version. 有特定.psp Photoshop的.psp首选项文件,但我无法查看其中的内容,而只是检查文件夹中是否有Photoshop文件,这对我来说似乎很草率,而且我需要获取版本。

Solution

After some research I came across the mac system profiler utility which seems to exist on all mac operating systems. 经过一番研究,我发现了所有Mac操作系统上都存在的mac system profiler实用程序。

using node 's exec module I get all installed applications and some details about each that look like 使用nodeexec模块,我得到了所有已安装的应用程序以及每个类似的详细信息

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 

now I just needed to write a simple parser to parse the results which were large with over 335 applications into json for easy querying. 现在,我只需要编写一个简单的解析器,即可将包含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 );
} );

the sysProfileTxtToJson is my little parsing method sysProfileTxtToJson是我的小解析方法

now parsed is a json object that I query to determine if photoshop is installed and if multiple version which is the latest version. 现在parsed是一个json对象,我查询该对象以确定是否已安装photoshop以及是否有多个版本(即最新版本)。

here is the parsing method of which needs improved 这是需要改进的解析方法

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 );
        } );
    } );
}

There are several features in AppleScript which can be utilized to achieve your requirement. AppleScript中有几个功能可以用来满足您的要求。 Consider shelling out the necessary AppleScript/ osascript commands via nodejs. 考虑炮击了必要的AppleScript / osascript通过命令的NodeJS。


Let's firstly take a look at the pertinent AppleScript commands... 首先让我们看一下相关的AppleScript命令...

AppleScript snippets: AppleScript片段:

  1. The following AppleScript snippet returns the name of whichever version of Photoshop is installed (Eg Photoshop CS5 , Photoshop CS6 , Photoshop CC , etc ...). 以下AppleScript代码段返回安装的Photoshop版本的名称(例如Photoshop CS5Photoshop CS6Photoshop CC等)。 We'll need the name to be able to successfully launch the application. 我们需要使用该名称才能成功启动该应用程序。

     tell application "Finder" to get displayed name of application file id "com.adobe.Photoshop" 

    Note: The snippet above errors if Photoshop is not installed, so we can also utilize this to determine if the application is installed or not. 注意:如果安装Photoshop,则上面的代码段错误,因此我们也可以利用它来确定是否已安装该应用程序。

  2. The following snippet obtains whichever version of Photoshop is installed: 以下代码片段获取安装的Photoshop版本:

     tell application "Finder" to get version of application file id "com.adobe.Photoshop" 

    This returns a long String indicating the version . 这将返回一个长字符串,指示版本 It will be something like this fictitious example: 这将是一个虚拟的示例:

    19.0.1 (19.0.1x20180407 [20180407.r.1265 2018/04/12:00:00:00) © 1990-2018 Adobe Systems Incorporated


Launching Photoshop: 启动Photoshop:

After it has been inferred that PhotoShop is installed consider utilizing Bash's open command to launch the application. 推断已安装PhotoShop后,请考虑利用Bash的open命令启动该应用程序。 For instance: 例如:

open -a "Adobe Photoshop CC"

Example node application: 节点应用程序示例:

The following gist demonstrates how the aforementioned commands can be utilized in node. 以下要点演示了如何在节点中利用上述命令。

Note: The gist below is utilizing shelljs 's exec command to execute the AppleScript/osascript commands. 注意:下面的要点是利用shelljsexec命令执行AppleScript / osascript命令。 However you could utilize nodes builtin child_process.execSync() or child_process.exec() instead. 但是,您可以child_process.execSync()内置在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');
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM