我有一个电子应用程序,它使用电子生成器分发。 这是main.js文件。该应用程序在ubuntu上运行,但是当我们为linux mint提供构建版本并单击任务栏图标时,它将自动关闭。首先,我给出了目标为“ deb”的构建。我尝试将其更改为“ AppImage”。 我尝试在Mac Windows和Linux上提供构建。它适用于除Linux Mint之外的所有三个。我已经尝试过
app.disableHardwareAcceleration();
app.commandLine.appendSwitch("disable-gpu");
app.commandLine.appendArgument("disable-gpu");
这是main.ts
import { app, BrowserWindow, screen, ipcMain, Tray, Menu, shell, nativeImage } from 'electron';
import * as ioHook from 'iohook';
import * as path from 'path';
import * as url from 'url';
import * as moment from 'moment';
import { CronJob } from 'cron';
import { notify } from 'node-notifier';
app.commandLine.appendSwitch("disable-gpu");
app.commandLine.appendArgument("disable-gpu");
let serve, size, isTrack, keyboardCount, mouseCount, screenshotTimerHandlers, settingData;
let takeScreenshotEvent, createNewActivityEvent, trayControlEvent, tray, selectProjectEvent, controlEvent;
let hourCronjobHandler, trackingIntervalHandler, engagementIntervalHandler, checkTrackOnHandler;
let contextMenu, currentTaskId, currentProjectId, selectedTaskId, selectedProjectId, previousTimestamp;
let idleSettingTimeInMins, lastTrackTimestamp, idleTimeInMilliSecs, lastProjectTimestamp, lastEngagementPer;
let projectsDetail, selectedProject, menuTemplate;
let trackingTimeIntervalMins, engagementTimeIntervalMins;
let win = null;
lastTrackTimestamp = 0;
lastProjectTimestamp = 0;
idleTimeInMilliSecs = 0;
keyboardCount = 0;
mouseCount = 0;
lastEngagementPer = 0;
currentTaskId = -1;
currentProjectId = -1;
selectedTaskId = -1;
selectedProjectId = -1;
previousTimestamp = 0;
trackingTimeIntervalMins = 0;
engagementTimeIntervalMins = 0;
isTrack = false;
settingData = {};
projectsDetail = {};
selectedProject = {};
menuTemplate = [];
screenshotTimerHandlers = [];
const args = process.argv.slice(1);
serve = args.some(val => val === '--serve');
app.disableHardwareAcceleration();
console.log(process.versions.electron , 'electron version');
function createWindow() {
const electronScreen = screen;
size = electronScreen.getPrimaryDisplay().workAreaSize;
// Create the browser window.
win = new BrowserWindow({
x: 0,
y: 0,
width: 1280,
height: 720,
// width: 472,
// height: 667,
center: true,
icon: nativeImage.createFromPath(path.join(__dirname, '/icons/256x256.png')),
minWidth: 472,
minHeight: 667,
// maxWidth: 472,
// maxHeight: 667,
maximizable: true,
minimizable: true,
webPreferences:{
webSecurity: false,
}
// width: size.width,x
// height: size.height
});
if (serve) {
require('electron-reload')(__dirname, {
electron: require(`${__dirname}/node_modules/electron`)
});
win.loadURL('http://localhost:4200');
} else {
win.loadURL(url.format({
pathname: path.join(__dirname, 'dist/index.html'),
protocol: 'file:',
slashes: true
}));
}
createTrayMenu();
initData();
// win.webContents.openDevTools();
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store window
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
// win.close();
if (win) {
win = null;
}
});
}
/**
* init data
*/
function initData() {
idleTimeInMilliSecs = 0;
projectsDetail = {};
// customNotify('Test', 'Test');
}
function customNotify(title, message) {
notify({
title: title,
message: message
}, (err, res) => {
});
}
/**
* create tray menu
*/
function createTrayMenu() {
/**
* Set tray icon
*/
const iconPath = path.join(__dirname, 'icons', '16x16.png');
tray = new Tray(iconPath);
menuTemplate = [
{
label: updateEngagement(0)
},
{
label: '',
visible: false
},
{
type: 'separator'
},
{
label: 'Timer is running',
click: () => {
if (currentProjectId >= 0 && trayControlEvent) {
trayControlEvent.sender.send('tray-icon-control-reply', {
status: 'stop',
taskId: currentTaskId,
projectId: currentProjectId
});
}
},
icon: path.join(__dirname, 'icons', 'pause.png'),
visible: false
},
{
label: 'Timer is paused',
click: () => {
if (selectedProjectId >= 0 && trayControlEvent) {
trayControlEvent.sender.send('tray-icon-control-reply', {
status: 'start',
taskId: selectedTaskId,
projectId: selectedProjectId
});
}
},
icon: path.join(__dirname, 'icons', 'play.png'),
enabled: false
},
{
type: 'separator'
},
{
label: 'Switch Projects',
},
{
type: 'separator'
},
{
label: 'Add a note',
click: () => {
controlEvent.sender.send('control-event-reply', {type: 'note'});
win.focus();
},
enabled: false
},
{
type: 'separator'
},
{
label: 'Open Dashboard',
click: () => {
shell.openExternal('https://tracklyapp.appup.cloud/trackly/#/430/1587/dashboard');
}
},
{
type: 'separator'
},
{
label: 'Settings',
click: () => {
controlEvent.sender.send('control-event-reply', {type: 'setting'});
win.focus();
}
},
{
type: 'separator'
},
{
label: 'About Track.ly',
click: () => {
shell.openExternal('https://www.track.ly/');
}
},
{
type: 'separator'
},
{
label: 'Help',
click: () => {
controlEvent.sender.send('control-event-reply', {type: 'help'});
win.focus();
}
},
{
type: 'separator'
},
{
label: 'Check for updates',
click: () => {
controlEvent.sender.send('control-event-reply', {type: 'check'});
win.focus();
}
},
{
type: 'separator'
},
{
label: 'Sign out',
click: () => {
controlEvent.sender.send('control-event-reply', {type: 'signout'});
menuTemplate[4].enabled = false;
win.focus();
}
},
{
type: 'separator'
},
{
label: 'Quit tracker',
click: () => {
if (win) {
win = null;
}
app.quit();
}
}
];
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
tray.setToolTip('Time Tracker');
}
/**
* destroy ipcMain listeners and cron job handler
*/
function destroyListners() {
if (ipcMain) {
ipcMain.removeAllListeners('get-current-ids');
ipcMain.removeAllListeners('get-selected-ids');
ipcMain.removeAllListeners('get-window-size');
ipcMain.removeAllListeners('take-screenshot');
ipcMain.removeAllListeners('select-task');
ipcMain.removeAllListeners('start-track');
ipcMain.removeAllListeners('stop-track');
ipcMain.removeAllListeners('create-new-activity');
ipcMain.removeAllListeners('tray-icon-control');
ipcMain.removeAllListeners('select-project');
ipcMain.removeAllListeners('control-event');
}
if (trackingIntervalHandler) {
clearInterval(trackingIntervalHandler);
}
if (engagementIntervalHandler) {
clearInterval(engagementIntervalHandler);
}
if (checkTrackOnHandler) {
clearInterval(checkTrackOnHandler);
}
if (hourCronjobHandler) {
hourCronjobHandler.stop();
}
}
// function parseCookies (rc) {
// var list = {};
// rc && rc.split(';').forEach(function( cookie ) {
// var parts = cookie.split('=');
// list[parts.shift().trim()] = decodeURI(parts.join('='));
// });
// return list;
// }
try {
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
// if (process.platform !== 'darwin') {
// }
app.quit();
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow();
}
});
app.on('before-quit', (evt) => {
if (tray) {
tray.destroy();
tray = null;
}
ioHook.stop();
ioHook.unload();
destroyListners();
});
/**
* Cron Job for Engagement
*/
hourCronjobHandler = new CronJob('0 0 */1 * * *', () => {
if (contextMenu && menuTemplate.length > 0) {
console.log('engagement cronjob running:');
const engagementPer = round(calculateEngagementPer(), 2);
menuTemplate[0].label = updateEngagement(engagementPer);
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
lastEngagementPer = engagementPer;
idleTimeInMilliSecs = 0;
}
// check the reset time
const currentTime = new Date();
const currentHours = currentTime.getHours();
const currentMinutes = currentTime.getMinutes();
if (currentHours === 0 && currentMinutes === 0) {
for (const key in projectsDetail) {
if (projectsDetail.hasOwnProperty(key)) {
projectsDetail[key]['time'] = 0;
}
}
}
}, null, true);
/**
* ipcMain lisner to get current task id and project id
*/
ipcMain.on('get-current-ids', (event, arg) => {
event.sender.send('get-current-ids-reply', {
currentTaskId: currentTaskId,
currentProjectId: currentProjectId
});
});
/**
* ipcMain lisner to get selected task id and project id
*/
ipcMain.on('get-selected-ids', (event, arg) => {
event.sender.send('get-selected-ids-reply', {
selectedTaskId: selectedTaskId,
selectedProjectId: selectedProjectId
});
});
/**
* ipcMain lisner to get current desktop window size
*/
ipcMain.on('get-window-size', (event, arg) => {
event.sender.send('get-window-size-reply', size);
});
/**
* ipcMain lisner to get screenshot event
*/
ipcMain.on('take-screenshot', (event, arg) => {
takeScreenshotEvent = event;
});
/**
* ipcMain lisner to get control event
*/
ipcMain.on('control-event', (event, arg) => {
controlEvent = event;
});
/**
* ipcMain lisner to get task id selected
*/
ipcMain.on('select-task', (event, arg) => {
if (currentProjectId < 0 && currentTaskId < 0) {
selectedTaskId = parseInt(arg['taskId'], 10);
selectedProjectId = parseInt(arg['projectId'], 10);
event.sender.send('get-selected-ids-reply', {
selectedTaskId: selectedTaskId,
selectedProjectId: selectedProjectId
});
if (tray && menuTemplate.length > 0) {
menuTemplate[3].visible = false;
menuTemplate[4].visible = true;
menuTemplate[4].enabled = true;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
}
});
/**
* ipcMain lisner to quit the app
*/
ipcMain.on('quit-app', (event, arg) => {
if (win) {
win = null;
}
app.quit();
});
/**
* ipcMain lisner to get start time tracking event
*/
ipcMain.on('start-track', (event, arg) => {
if (currentTaskId >= 0 && currentProjectId >= 0) {
if (currentTaskId !== arg['taskId'] || currentProjectId !== arg['projectId']) {
isTrack = false;
if (tray && menuTemplate.length > 0) {
menuTemplate[3].visible = false;
menuTemplate[4].visible = true;
menuTemplate[4].enabled = true;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
updateTracks(currentProjectId, currentTaskId, Date.now());
clearTrackData();
}
}
isTrack = true;
lastTrackTimestamp = Date.now();
if (tray && menuTemplate.length) {
menuTemplate[3].visible = true;
menuTemplate[4].visible = false;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
currentTaskId = arg['taskId'];
selectedTaskId = arg['taskId'];
currentProjectId = arg['projectId'];
selectedProjectId = arg['projectId'];
previousTimestamp = Date.now();
// takeScreenShots(currentTaskId, trackingTimeIntervalMins * 60 * 1000, true);
event.sender.send('start-track-reply', {
currentTaskId: currentTaskId,
currentProjectId: currentProjectId,
selectedTaskId: selectedTaskId,
selectedProjectId: selectedProjectId
});
});
/**
* ipcMain lisner to get stop time tracking event
*/
ipcMain.on('stop-track', (event, arg) => {
if (isTrack) {
updateTracks(arg['projectId'], arg['taskId'], Date.now());
clearTrackData();
if (tray && menuTemplate.length > 0) {
menuTemplate[3].visible = false;
menuTemplate[4].visible = true;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
event.sender.send('stop-track-reply', {
currentTaskId: currentTaskId,
currentProjectId: currentProjectId,
selectedTaskId: selectedTaskId,
selectedProjectId: selectedProjectId
});
}
});
/**
* ipcMain lisner to update setting
*/
ipcMain.on('update-setting', (event, arg) => {
settingData = arg['setting'];
checkTrackOnStatus();
});
/**
* ipcMain lisner to select project
*/
ipcMain.on('select-project', (event, arg) => {
const current = Date.now();
selectProjectEvent = event;
selectedProject = arg['project'];
if (selectedProject['id']) { // if project is selected
selectedProjectId = selectedProject['id'];
idleSettingTimeInMins = selectedProject['ideal_time_interval_mins'] ? parseInt(selectedProject['ideal_time_interval_mins'], 10) : 0;
trackingTimeIntervalMins = selectedProject['time_interval_mins'] ? parseInt(selectedProject['time_interval_mins'], 10) : 0;
engagementTimeIntervalMins = selectedProject['engagement_interval_mins'] ?
parseInt(selectedProject['engagement_interval_mins'], 10) : 0;
clearTimeIntervals();
startTimeIntervals();
lastProjectTimestamp = current;
if (tray && menuTemplate.length > 0) {
menuTemplate[3].visible = false;
menuTemplate[4].visible = true;
menuTemplate[4].enabled = true;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
buildProjectInfo();
} else { // if any project is not selected
if (
isTrack &&
Object.keys(selectedProject).length !== 0 &&
selectedProject['id'] &&
projectsDetail.hasOwnProperty(selectedProject['id'])
) { // if there is previous selected project
const diffInMilliSecs = current - lastProjectTimestamp;
projectsDetail[selectedProject['id']]['time'] += diffInMilliSecs;
}
selectedProject = {};
selectedProjectId = -1;
if (tray) {
if (tray && menuTemplate.length > 0 && !isTrack) {
menuTemplate[1].visible = false;
menuTemplate[3].visible = false;
menuTemplate[4].visible = true;
menuTemplate[4].enabled = false;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
}
}
});
/**
* ipcMain lisner to get all projects and tasks
*/
ipcMain.on('get-all-projects-tasks', (event, arg) => {
let projectSubMenu = [];
if (arg['projects'] && arg['projects'].length > 0) {
for (let index = 0; index < arg['projects'].length; index ++) {
if (arg['projects'][index] && arg['projects'][index]['id']) {
if (!projectsDetail.hasOwnProperty(arg['projects'][index]['id'])) {
projectsDetail[arg['projects'][index]['id']] = {
time: 0
};
}
projectsDetail[arg['projects'][index]['id']]['data'] = arg['projects'][index];
}
}
projectSubMenu = buildProjectMenu(arg['projects'], arg['tasks']);
}
if (tray && menuTemplate.length > 3) {
if (projectSubMenu.length > 0) {
menuTemplate[6].submenu = projectSubMenu;
}
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
});
/**
* ipcMain activity lisner
*/
ipcMain.on('activity-notification', (event, arg) => {
if (tray && menuTemplate.length > 0) {
menuTemplate[8].enabled = true;
contextMenu = Menu.buildFromTemplate(menuTemplate);
tray.setContextMenu(contextMenu);
}
});
/**
* ipcMain lisner to get event of tray icon control
*/
ipcMain.on('tray-icon-control', (event, arg) => {
trayControlEvent = event;
});
/**
* ipcMain lisner to get event of new activity creation
*/
ipcMain.on('create-new-activity', (event, arg) => {
createNewActivityEvent = event;
});
/**
* ioHook listener to get key down event
*/
ioHook.on('keydown', event => {
if (isTrack) {
keyboardCount ++;
lastTrackTimestamp = Date.now();
}
});
/**
* ioHook listener to get mouse down event
*/
ioHook.on('mousedown', event => {
if (isTrack) {
mouseCount ++;
lastTrackTimestamp = Date.now();
}
});
// Register and start hook
ioHook.start(false);
} catch (e) {
console.log('error: ', e);
// Catch Error
// throw e;
}
单击任务栏图标后,该应用程序将在Linux Mint中强制关闭。但这不是在Windows / Mac和Ubuntu中发生的。它仅在Linux Mint上发生。请帮忙。