问题
Is there a way to keep my Electron app I developed in the dock? My goal is to have the user download the .app file, launch it (which it does automatically) and then on the MAC "Keep In Dock" after they close it. I know this can be done with dockutil, but I need a way to do it within the application.
回答1:
I have some working code on macOS 10.11.6 (El Capitan) which permanently adds the current app to the Dock, but unfortunately I don't really know how to check if the icon is already in the Dock, so running the code once again will add a new one each time.
Note also that killing the Dock is necessary to update it, but this may upset the user when it disappears for a few seconds...
Anyway, here it the code, which can be used as a starting base:
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' });
}
回答2:
Here is some improved code which performs an initial test (defaults read
piped to grep
) to ensure that only one instance of the app gets permanently kept in the Dock. It has been successfully tested on both macOS Yosemite and 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)
}
来源:https://stackoverflow.com/questions/50876417/electron-mac-keep-in-dock