Macos 电子-MAC保持在船坞中

Macos 电子-MAC保持在船坞中,macos,electron,Macos,Electron,有没有办法让我开发的电子应用程序留在被告席上?我的目标是让用户下载.app文件,启动它(它会自动启动),然后在关闭它后在MAC上“保持在Dock中”。我知道这可以用dockutil实现,但我需要一种在应用程序中实现的方法。我在macOS 10.11.6(El Capitan)上有一些工作代码,可以永久性地将当前应用程序添加到Dock,但不幸的是,我真的不知道如何检查图标是否已经在Dock中,因此,再次运行代码将每次添加一个新代码 还要注意的是,关闭Dock是更新它的必要条件,但当Dock消失几秒

有没有办法让我开发的电子应用程序留在被告席上?我的目标是让用户下载.app文件,启动它(它会自动启动),然后在关闭它后在MAC上“保持在Dock中”。我知道这可以用dockutil实现,但我需要一种在应用程序中实现的方法。

我在macOS 10.11.6(El Capitan)上有一些工作代码,可以永久性地将当前应用程序添加到Dock,但不幸的是,我真的不知道如何检查图标是否已经在Dock中,因此,再次运行代码将每次添加一个新代码

还要注意的是,关闭Dock是更新它的必要条件,但当Dock消失几秒钟时,这可能会让用户感到不安

无论如何,这里是代码,它可以作为一个起点:

const electron = require ('electron');
const app = electron.app || electron.remote.app;
const path = require ('path');
const url = require ('url');
const { spawnSync } = require ('child_process');
let packagePath = path.join (app.getPath ('exe'), '..', '..', '..');
let packageURL = url.format ({ protocol: 'file', slashes: true, pathname: packagePath });
let entry = `<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${packageURL}</string><key>_CFURLStringType</key><integer>15</integer></dict></dict></dict>`;
let defaults = spawnSync ('defaults', [ 'write', 'com.apple.dock', 'persistent-apps', '-array-add', entry ], { encoding: 'utf8' });
if (!defaults.error)
{
    let killall = spawnSync ('killall', [ 'Dock' ], { encoding: 'utf8' });
}
const electron=require('electron');
const app=electron.app | | electron.remote.app;
const path=require('path');
const url=require('url');
const{spawnSync}=require('child_进程');
让packagePath=path.join(app.getPath('exe')、'..'、'..'和'..');
让packageURL=url.format({协议:'file',斜杠:true,路径名:packagePath});
let entry=`tile-datafile-data\u CFURLString${packageURL}\u CFURLStringType15`;
让defaults=spawnSync('defaults',['write','com.apple.dock','persistent apps','-array add',entry],{encoding:'utf8'});
如果(!defaults.error)
{
让killall=spawnSync('killall',['Dock'],{encoding:'utf8'});
}
这里有一些改进,它执行初始测试(
默认读取
管道传输到
grep
),以确保只有一个应用程序实例永久保留在Dock中。它已经在马科斯约塞米蒂和El Capitan上成功测试过

const electron = require ('electron');
const app = electron.app || electron.remote.app;
const path = require ('path');
const url = require ('url');
const { spawnSync } = require ('child_process');
//
function isAppInDock (appURL)
{
    let isInDock = false;
    let defaults = spawnSync ('defaults', [ 'read', 'com.apple.dock', 'persistent-apps' ], { encoding: 'utf8' });
    if (!defaults.error)
    {
        let pattern = `"_CFURLString" = "${appURL}"`;
        let grep = spawnSync ('grep', [ '-F', pattern ], { input: defaults.stdout, encoding: 'utf8' });
        if (!grep.error)
        {
            if (grep.stdout.length)
            {
                isInDock = true;
            }
        }
    }
    return isInDock;
}
//
function keepAppInDock (appURL)
{
    let entry = `<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${appURL}</string><key>_CFURLStringType</key><integer>15</integer></dict></dict></dict>`;
    let defaults = spawnSync ('defaults', [ 'write', 'com.apple.dock', 'persistent-apps', '-array-add', entry ], { encoding: 'utf8' });
    if (!defaults.error)
    {
        let killall = spawnSync ('killall', [ 'Dock' ], { encoding: 'utf8' });
    }
}
//
let appPackagePath = path.join (app.getPath ('exe'), '..', '..', '..');
let appPackageURL = encodeURI (url.format ({ protocol: 'file', slashes: true, pathname: appPackagePath })) + '/';
//
if (!isAppInDock (appPackageURL))
{
    keepAppInDock (appPackageURL)
}
const electron=require('electron');
const app=electron.app | | electron.remote.app;
const path=require('path');
const url=require('url');
const{spawnSync}=require('child_进程');
//
函数isAppInDock(appURL)
{
让isInDock=false;
让defaults=spawnSync('defaults',['read','com.apple.dock','persistent apps'],{encoding:'utf8'});
如果(!defaults.error)
{
让模式=`“\CFURLString”=“${appURL}”`;
让grep=spawnSync('grep',['-F',pattern],{input:defaults.stdout,encoding:'utf8'});
如果(!grep.error)
{
if(grep.stdout.length)
{
isInDock=true;
}
}
}
返回isInDock;
}
//
函数keepAppInDock(appURL)
{
let entry=`tile-datafile-data\u CFURLString${appURL}\u CFURLStringType15`;
让defaults=spawnSync('defaults',['write','com.apple.dock','persistent apps','-array add',entry],{encoding:'utf8'});
如果(!defaults.error)
{
让killall=spawnSync('killall',['Dock'],{encoding:'utf8'});
}
}
//
让appPackagePath=path.join(app.getPath('exe')、'..'、'..'、'..'、'..');
让appPackageURL=encodeURI(url.format({protocol:'file',slashes:true,pathname:appPackagePath}))+'/';
//
如果(!isAppInDock(appPackageURL))
{
keepAppInDock(appPackageURL)
}

谢谢你,汉斯,这个代码对我来说不是“保存在文档中”。该应用程序已经出现在码头上了,我只需要它在他们启动后永久停留在那里。我试图避免让用户进入他们的应用程序文件夹,从那里启动它,然后单击cmd+选择“保持在Dock中”。@TheDickens,作为Mac用户,我只看到一个应用程序将自己添加到我的Dock中一两次,这让我非常愤怒。对于一个Mac开发者来说,除了尝试将他们自己添加到我的Dock或桌面上,没有任何可靠的方法能让我相信他们不了解边界。对我来说,这台电脑相当于你走进我家挂自己的照片。未经我的明确同意,请勿在我的被告席上添加内容,并通过让我单击“保持被告席”获得我的明确同意。说得好,是的,我同意。如果我让它工作,那么我将添加一个选项,询问用户是否希望将其添加到他们的dock中。是的,我意识到这是一个奇怪的要求,我无法解释为什么必须这样做。迄今为止,最好的解决方案,经过测试,它是有效的,是的,如果有一种方法可以检测图标是否在那里,就像你说的那样,这将是完整的。惊人的,这是完美的!非常感谢。现在添加“是否要将此图标添加到dock?”选项。我有时间实施此解决方案。但是,在我退出应用程序并重新打开它之后,它会创建一个重复的图标吗?或硬盘驱动器图标。我假设脚本没有发现/applicationname.app已经存在。我没有任何线索。您可能需要调试代码并测试ISappingDock的结果。。。此外,您还可以在终端窗口中“手动”检查
默认值读取com.apple.dock persistent apps的结果,以检查dock中意外图标所指的内容。。。