├── .eslintignore ├── .gitignore ├── .xo-config.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── dist ├── index.d.ts ├── index.js └── index.js.map ├── package-lock.json ├── package.json ├── src └── index.ts └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuelcarreira/electron-shutdown-command/98ee2dd21036e7c9cee80f08e165448611ba83e8/.eslintignore -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | .jshintrc -------------------------------------------------------------------------------- /.xo-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "xo-typescript", 3 | "extensions": [ 4 | "ts" 5 | ], 6 | "ignores": [ 7 | "sample-app/*" 8 | ], 9 | "space": true, 10 | "rules": { 11 | "no-dynamic-delete": 0, 12 | "expiring-todo-comments": 0, 13 | "@typescript-eslint/no-unused-expressions": "off", 14 | "@typescript-eslint/no-dynamic-delete": "off", 15 | "capitalized-comments": 1 16 | } 17 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [2.0.1] - 2020-10-06 6 | ### Changed 7 | - Updated dependencies 8 | - Add default parameter value (thanks @brunobg) 9 | 10 | ## [2.0.0] - 2020-07-20 11 | ### Changed 12 | - Completely rewrite in TypeScript 13 | 14 | ## [0.0.7] - 2017-09-13 15 | ### Fixed 16 | - Fixed abort bug (thanks @fabianbehrendt) -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are always welcome, no matter how large or small. 4 | This is my first public Node module so all help or suggestions will be very appreciated. 5 | 6 | Please send pull requests improving the usage and fixing bugs, improving documentation and providing better examples, or providing some tests, because these things are important. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Samuel Carreira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Electron Shutdown Command 2 | 3 | Quickly shutdown, reboot, log off, halt, restarts, etc. your computer using the native shutdown command easily from an electron app. Cross platform (Windows; macOS and Linux) 4 | 5 | 6 | ## ATTENTION macOS and Linux Users: 7 | **You need to run the app as sudo/root to allow to run the shutdown command!** 8 | 9 | 10 | ## Key Features 11 | * **Secure and lightweight:** Uses only node/electron native modules 12 | 13 | * **Written in TypeScript** 14 | 15 | * **Well documented and easy to use** 16 | 17 | 18 | ## Installation 19 | ``` 20 | npm install --save electron-shutdown-command 21 | ``` 22 | or 23 | 24 | ``` 25 | yarn add electron-shutdown-command 26 | ``` 27 | 28 | 29 | ## Usage 30 | 31 | ``` 32 | const shutdown = require('electron-shutdown-command'); 33 | 34 | shutdown.shutdown(); // simple system shutdown with default options 35 | ``` 36 | or 37 | ``` 38 | import * as shutdown from 'electron-shutdown-command'; 39 | 40 | shutdown.shutdown(); // simple system shutdown with default options 41 | ``` 42 | or 43 | 44 | ``` 45 | /* shutdown after 60 seconds, force all windows to close (Microsoft Windows only), 46 | * run as sudo (macOS and Linux only), debug command to console 47 | * (not execute it) and quit app after the command execution 48 | */ 49 | shutdown.shutdown({ 50 | force: true, 51 | timerseconds: 60, 52 | sudo: true, 53 | debug: true, 54 | quitapp: true 55 | }) 56 | ``` 57 | or 58 | ``` 59 | // Warning: Microsoft Windows only 60 | shutdown.logoff(); 61 | ``` 62 | 63 | 64 | ## Methods 65 | 66 | ### shutdown([options]) 67 | > shutdown / power-off your machine 68 | 69 | ### reboot([options]) 70 | > Reboot / restarts your machine 71 | 72 | ### logoff([options]) 73 | > Ends current session *Windows only* 74 | 75 | ### sleep([options]) 76 | > Enters sleep mode *macOS only* 77 | 78 | ### hibernate([options]) 79 | > Hibernate *Windows only* 80 | 81 | ### abort([options]) 82 | > Aborts or cancels a pending shutdown (this does not apply to "shutdown now", which does not wait before shutting down) *Windows and Linux only* 83 | 84 | ## Options 85 | 86 | Property | Type | Default | Description 87 | ---------------- | -------- | ---------- | ---------------------- 88 | `force` | `boolean` | `false` | Forces running applications to close *Windows only* 89 | `sudo` | `boolean` | `false` | Run command as sudo *macOS and Linux* 90 | `debug` | `boolean` | `false` | Shows shutdown command on console for debugging purposes **NOTE: It does not run it** 91 | `quitapp` | `boolean` | `false` | Quits your app after the shutdown command 92 | `timerseconds` | `number` | `0` | Sets the timer (value in seconds). **NOTES**: in *macOS* the minimum is 1 minute. The logoff, sleep and hibernate option cannot be scheduled, they are executed immediately 93 | 94 | 95 | ## Motivation and history 96 | I quickly wrote this library because I need to add a shutdown option to an Electron Windows App. This is a very simple library that justs executes the shutdown command on different OS. **Warning:** I didn't have enough time to fully test this module on macOS and Linux. If there is enough interest in some specific platform I can try to improve this module (I currently use this module on Windows 10). 97 | 98 | ## Contribution 99 | Please send pull requests improving the usage and fixing bugs, improving documentation and providing better examples, or providing some tests, because these things are important. 100 | 101 | 102 | ## Learn More 103 | Shutdown command 104 | * Windows: https://technet.microsoft.com/en-us/library/bb491003.aspx?f=255&MSPPError=-2147217396 105 | * macOS: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/shutdown.8.html 106 | * Linux: https://www.computerhope.com/unix/ushutdow.htm 107 | 108 | * [Create Shortcuts on the Desktop to Run Programs as Root in Ubuntu 11.10](https://www.howtogeek.com/112700/create-shortcuts-on-the-desktop-to-run-programs-as-root-in-ubuntu-11.10/) 109 | * [How to Run GUI Apps as root in Mac OS X](https://osxdaily.com/2013/02/06/how-to-run-gui-apps-as-root-in-mac-os-x/) 110 | 111 | ## License 112 | - Licensed under MIT 113 | 114 | - Copyright (c) 2017-2020 [Samuel Carreira] -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Electron Shutdown Command 3 | * 4 | * Learn more - documentation: 5 | * windows: https://technet.microsoft.com/en-us/library/bb491003.aspx?f=255&MSPPError=-2147217396 6 | * macos: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/shutdown.8.html 7 | * linux: https://www.computerhope.com/unix/ushutdow.htm 8 | * 9 | * Licensed under MIT 10 | * Copyright (c) 2020 [Samuel Carreira] 11 | */ 12 | export interface ElectronShutdownCommandUserOptions { 13 | /** 14 | * Sets the timer (value in seconds). 15 | * Notes: in macOS the minimum is 1 minute. The logoff, sleep 16 | * and hibernate option cannot be scheduled, it executes immediately 17 | * 18 | * @default 0 19 | */ 20 | timerseconds?: number; 21 | /** 22 | * Quits your app after the shutdown command 23 | * 24 | * @default false 25 | */ 26 | quitapp?: boolean; 27 | /** 28 | * Run as sudo *macOS and Linux only* 29 | * 30 | * @default false 31 | */ 32 | sudo?: boolean; 33 | /** 34 | * Forces running applications to close *Windows only* 35 | * 36 | * @default false 37 | */ 38 | force?: boolean; 39 | /** 40 | * Shows shutdown command on console for debugging 41 | * purposes **NOTE: It does not run it** 42 | * 43 | * @default false 44 | */ 45 | debug?: boolean; 46 | } 47 | /** 48 | * Shutdown command 49 | * 50 | * @param {object} options 51 | */ 52 | export declare function shutdown(options?: ElectronShutdownCommandUserOptions): void; 53 | /** 54 | * Hibernate (Windows only) 55 | * @param {Object} options 56 | */ 57 | export declare function hibernate(options?: ElectronShutdownCommandUserOptions): void; 58 | /** 59 | * Ends current session (Windows only) 60 | * @param {object} options 61 | */ 62 | export declare function logoff(options?: ElectronShutdownCommandUserOptions): void; 63 | /** 64 | * Enters sleep mode (macOS Only) 65 | */ 66 | export declare function sleep(options?: ElectronShutdownCommandUserOptions): void; 67 | /** 68 | * Aborts current scheduled shutdown 69 | * @param {Object} options 70 | */ 71 | export declare function abort(options?: ElectronShutdownCommandUserOptions): void; 72 | /** 73 | * Shutdown / power-off your machine 74 | * @param {Object} options 75 | */ 76 | export declare function reboot(options?: ElectronShutdownCommandUserOptions): void; 77 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /*! 3 | * Electron Shutdown Command 4 | * 5 | * Learn more - documentation: 6 | * windows: https://technet.microsoft.com/en-us/library/bb491003.aspx?f=255&MSPPError=-2147217396 7 | * macos: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/shutdown.8.html 8 | * linux: https://www.computerhope.com/unix/ushutdow.htm 9 | * 10 | * Licensed under MIT 11 | * Copyright (c) 2020 [Samuel Carreira] 12 | */ 13 | Object.defineProperty(exports, "__esModule", { value: true }); 14 | exports.reboot = exports.abort = exports.sleep = exports.logoff = exports.hibernate = exports.shutdown = void 0; 15 | const cp = require("child_process"); 16 | const electron_1 = require("electron"); 17 | function applyDefaults(options) { 18 | const defaultOptions = { 19 | timerseconds: 0, 20 | quitapp: false, 21 | sudo: false, 22 | force: false, 23 | debug: false 24 | }; 25 | return { ...defaultOptions, ...options }; 26 | } 27 | /** 28 | * Shutdown command 29 | * 30 | * @param {object} options 31 | */ 32 | function shutdown(options = {}) { 33 | const validatedOptions = applyDefaults(options); 34 | const cmdarguments = ['shutdown']; 35 | if (process.platform === 'linux' || process.platform === 'darwin') { 36 | if (options.sudo) { 37 | cmdarguments.unshift('sudo'); 38 | } 39 | cmdarguments.push('-h'); // Halt 40 | } 41 | if (process.platform === 'win32') { 42 | cmdarguments.push('-s'); // Shutdown 43 | if (options.force) { 44 | cmdarguments.push('-f'); 45 | } 46 | } 47 | cmdarguments.push(...setTimer(validatedOptions.timerseconds)); 48 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 49 | } 50 | exports.shutdown = shutdown; 51 | /** 52 | * Hibernate (Windows only) 53 | * @param {Object} options 54 | */ 55 | function hibernate(options = {}) { 56 | if (process.platform !== 'win32') { 57 | throw new Error('Unsupported OS (only Windows is supported)!'); 58 | } 59 | const validatedOptions = applyDefaults(options); 60 | const cmdarguments = ['shutdown']; 61 | cmdarguments.push('-h'); // Hibernate 62 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 63 | } 64 | exports.hibernate = hibernate; 65 | /** 66 | * Ends current session (Windows only) 67 | * @param {object} options 68 | */ 69 | function logoff(options = {}) { 70 | if (process.platform !== 'win32') { 71 | throw new Error('Unsupported OS (only Windows is supported)!'); 72 | } 73 | const validatedOptions = applyDefaults(options); 74 | const cmdarguments = ['shutdown']; 75 | cmdarguments.push('-l'); // Logoff 76 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 77 | } 78 | exports.logoff = logoff; 79 | /** 80 | * Enters sleep mode (macOS Only) 81 | */ 82 | function sleep(options = {}) { 83 | if (process.platform !== 'darwin') { 84 | throw new Error('Unsupported OS (only macOS is supported)!'); 85 | } 86 | const validatedOptions = applyDefaults(options); 87 | const cmdarguments = ['shutdown']; 88 | cmdarguments.push('-s'); // Sleep 89 | // cmdarguments.push(setTimer(options.timerseconds)); 90 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 91 | } 92 | exports.sleep = sleep; 93 | /** 94 | * Aborts current scheduled shutdown 95 | * @param {Object} options 96 | */ 97 | function abort(options = {}) { 98 | if (process.platform !== 'win32' && process.platform !== 'linux') { 99 | throw new Error('Unsupported OS (only Windows and Linux are supported)!'); 100 | } 101 | const validatedOptions = applyDefaults(options); 102 | const cmdarguments = ['shutdown']; 103 | if (process.platform === 'win32') { 104 | cmdarguments.push('-a'); // Abort 105 | } 106 | else { 107 | // Linux 108 | cmdarguments.push('-c'); // Cancel a pending shutdown 109 | } 110 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 111 | } 112 | exports.abort = abort; 113 | /** 114 | * Shutdown / power-off your machine 115 | * @param {Object} options 116 | */ 117 | function reboot(options = {}) { 118 | const validatedOptions = applyDefaults(options); 119 | const cmdarguments = ['shutdown']; 120 | cmdarguments.push('-r'); // Reboot 121 | if (process.platform === 'linux' || process.platform === 'darwin') { 122 | if (options.sudo) { 123 | cmdarguments.unshift('sudo'); 124 | } 125 | } 126 | if (process.platform === 'win32') { 127 | if (options.force) { 128 | cmdarguments.push('-f'); 129 | } 130 | } 131 | cmdarguments.push(...setTimer(validatedOptions.timerseconds)); 132 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 133 | } 134 | exports.reboot = reboot; 135 | /** 136 | * Set current time argument 137 | * @param {Number} timervalue value in seconds to delay, false to execute now 138 | */ 139 | function setTimer(timervalue) { 140 | const cmdarguments = []; 141 | if (process.platform === 'linux') { 142 | if (timervalue) { 143 | cmdarguments.push(timervalue.toString()); 144 | } 145 | else { 146 | cmdarguments.push('now'); 147 | } 148 | } 149 | if (process.platform === 'darwin') { 150 | if (timervalue) { 151 | let timeinminutes = Math.round(Number(timervalue) / 60); 152 | if (timeinminutes === 0) { 153 | timeinminutes = 1; // Minimum 1 minute 154 | } 155 | cmdarguments.push(`-t ${timeinminutes.toString()}`); 156 | } 157 | else { 158 | cmdarguments.push('now'); 159 | } 160 | } 161 | if (process.platform === 'win32') { 162 | if (timervalue) { 163 | cmdarguments.push(`-t ${timervalue.toString()}`); 164 | } 165 | else { 166 | cmdarguments.push('-t 0'); // Set to 0 because default is 20 seconds 167 | } 168 | } 169 | return cmdarguments; 170 | } 171 | /** 172 | * Execute command 173 | 174 | * @param {Boolean} debug show console results, not execute the command 175 | * @param {Boolean} quitapp quit app after send the command 176 | */ 177 | function executeCmd(cmd, debug, quitapp) { 178 | const finalcmd = cmd.join(' '); 179 | if (debug) { 180 | // Debug mode, print to console 181 | console.log(`Debug shutdown command: ${finalcmd}`); 182 | if (quitapp) { 183 | console.log('Now exit app...'); 184 | electron_1.app.exit(0); 185 | } 186 | return; 187 | } 188 | // Execute the command 189 | cp.exec(finalcmd, err => { 190 | if (err) { 191 | console.error(err); 192 | return; 193 | } 194 | if (quitapp) { 195 | electron_1.app.exit(0); 196 | } 197 | }); 198 | } 199 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-shutdown-command", 3 | "productName": "Electron Shutdown Command", 4 | "version": "2.0.1", 5 | "description": "Quickly shutdown, reboot, log off, halt, your computer using the native shutdown command easily from an electron app. Cross platform (Windows; macOS and Linux)", 6 | "main": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "build": "tsc", 11 | "watch": "tsc -w", 12 | "publish": "npm publish", 13 | "lint": "xo" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/samuelcarreira/electron-shutdown-command.git" 18 | }, 19 | "keywords": [ 20 | "shutdown", 21 | "poweroff", 22 | "reboot", 23 | "halt", 24 | "restart", 25 | "electron" 26 | ], 27 | "author": "Samuel Carreira (http://www.samuelcarreira.com)", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/samuelcarreira/electron-shutdown-command/issues" 31 | }, 32 | "homepage": "https://github.com/samuelcarreira/electron-shutdown-command#readme", 33 | "devDependencies": { 34 | "electron": "^10.1.2", 35 | "typescript": "^4.0.3", 36 | "xo": "^0.33.1" 37 | }, 38 | "files": [ 39 | "dist/**/*" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Electron Shutdown Command 3 | * 4 | * Learn more - documentation: 5 | * windows: https://technet.microsoft.com/en-us/library/bb491003.aspx?f=255&MSPPError=-2147217396 6 | * macos: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/shutdown.8.html 7 | * linux: https://www.computerhope.com/unix/ushutdow.htm 8 | * 9 | * Licensed under MIT 10 | * Copyright (c) 2020 [Samuel Carreira] 11 | */ 12 | 13 | import cp = require('child_process'); 14 | import {app} from 'electron'; 15 | 16 | export interface ElectronShutdownCommandUserOptions { 17 | /** 18 | * Sets the timer (value in seconds). 19 | * Notes: in macOS the minimum is 1 minute. The logoff, sleep 20 | * and hibernate option cannot be scheduled, it executes immediately 21 | * 22 | * @default 0 23 | */ 24 | timerseconds?: number; 25 | /** 26 | * Quits your app after the shutdown command 27 | * 28 | * @default false 29 | */ 30 | quitapp?: boolean; 31 | /** 32 | * Run as sudo *macOS and Linux only* 33 | * 34 | * @default false 35 | */ 36 | sudo?: boolean; 37 | /** 38 | * Forces running applications to close *Windows only* 39 | * 40 | * @default false 41 | */ 42 | force?: boolean; 43 | /** 44 | * Shows shutdown command on console for debugging 45 | * purposes **NOTE: It does not run it** 46 | * 47 | * @default false 48 | */ 49 | debug?: boolean; 50 | } 51 | 52 | interface ElectronShutdownCommandOptions { 53 | timerseconds: number; 54 | quitapp: boolean; 55 | sudo: boolean; 56 | force: boolean; 57 | debug: boolean; 58 | } 59 | 60 | function applyDefaults(options: ElectronShutdownCommandUserOptions): ElectronShutdownCommandOptions { 61 | const defaultOptions: ElectronShutdownCommandOptions = { 62 | timerseconds: 0, 63 | quitapp: false, 64 | sudo: false, 65 | force: false, 66 | debug: false 67 | }; 68 | 69 | return {...defaultOptions, ...options}; 70 | } 71 | 72 | /** 73 | * Shutdown command 74 | * 75 | * @param {object} options 76 | */ 77 | export function shutdown(options: ElectronShutdownCommandUserOptions = {}) { 78 | const validatedOptions: ElectronShutdownCommandOptions = applyDefaults(options); 79 | 80 | const cmdarguments = ['shutdown']; 81 | 82 | if (process.platform === 'linux' || process.platform === 'darwin') { 83 | if (options.sudo) { 84 | cmdarguments.unshift('sudo'); 85 | } 86 | 87 | cmdarguments.push('-h'); // Halt 88 | } 89 | 90 | if (process.platform === 'win32') { 91 | cmdarguments.push('-s'); // Shutdown 92 | 93 | if (options.force) { 94 | cmdarguments.push('-f'); 95 | } 96 | } 97 | 98 | cmdarguments.push(...setTimer(validatedOptions.timerseconds)); 99 | 100 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 101 | } 102 | 103 | /** 104 | * Hibernate (Windows only) 105 | * @param {Object} options 106 | */ 107 | export function hibernate(options: ElectronShutdownCommandUserOptions = {}) { 108 | if (process.platform !== 'win32') { 109 | throw new Error('Unsupported OS (only Windows is supported)!'); 110 | } 111 | 112 | const validatedOptions: ElectronShutdownCommandOptions = applyDefaults(options); 113 | 114 | const cmdarguments = ['shutdown']; 115 | 116 | cmdarguments.push('-h'); // Hibernate 117 | 118 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 119 | } 120 | 121 | /** 122 | * Ends current session (Windows only) 123 | * @param {object} options 124 | */ 125 | export function logoff(options: ElectronShutdownCommandUserOptions = {}) { 126 | if (process.platform !== 'win32') { 127 | throw new Error('Unsupported OS (only Windows is supported)!'); 128 | } 129 | 130 | const validatedOptions: ElectronShutdownCommandOptions = applyDefaults(options); 131 | 132 | const cmdarguments = ['shutdown']; 133 | 134 | cmdarguments.push('-l'); // Logoff 135 | 136 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 137 | } 138 | 139 | /** 140 | * Enters sleep mode (macOS Only) 141 | */ 142 | export function sleep(options: ElectronShutdownCommandUserOptions = {}) { 143 | if (process.platform !== 'darwin') { 144 | throw new Error('Unsupported OS (only macOS is supported)!'); 145 | } 146 | 147 | const validatedOptions: ElectronShutdownCommandOptions = applyDefaults(options); 148 | 149 | const cmdarguments = ['shutdown']; 150 | 151 | cmdarguments.push('-s'); // Sleep 152 | 153 | // cmdarguments.push(setTimer(options.timerseconds)); 154 | 155 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 156 | } 157 | 158 | /** 159 | * Aborts current scheduled shutdown 160 | * @param {Object} options 161 | */ 162 | export function abort(options: ElectronShutdownCommandUserOptions = {}) { 163 | if (process.platform !== 'win32' && process.platform !== 'linux') { 164 | throw new Error('Unsupported OS (only Windows and Linux are supported)!'); 165 | } 166 | 167 | const validatedOptions: ElectronShutdownCommandOptions = applyDefaults(options); 168 | 169 | const cmdarguments = ['shutdown']; 170 | 171 | if (process.platform === 'win32') { 172 | cmdarguments.push('-a'); // Abort 173 | } else { 174 | // Linux 175 | cmdarguments.push('-c'); // Cancel a pending shutdown 176 | } 177 | 178 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 179 | } 180 | 181 | /** 182 | * Shutdown / power-off your machine 183 | * @param {Object} options 184 | */ 185 | export function reboot(options: ElectronShutdownCommandUserOptions = {}) { 186 | const validatedOptions: ElectronShutdownCommandOptions = applyDefaults(options); 187 | 188 | const cmdarguments = ['shutdown']; 189 | 190 | cmdarguments.push('-r'); // Reboot 191 | 192 | if (process.platform === 'linux' || process.platform === 'darwin') { 193 | if (options.sudo) { 194 | cmdarguments.unshift('sudo'); 195 | } 196 | } 197 | 198 | if (process.platform === 'win32') { 199 | if (options.force) { 200 | cmdarguments.push('-f'); 201 | } 202 | } 203 | 204 | cmdarguments.push(...setTimer(validatedOptions.timerseconds)); 205 | 206 | executeCmd(cmdarguments, validatedOptions.debug, validatedOptions.quitapp); 207 | } 208 | 209 | /** 210 | * Set current time argument 211 | * @param {Number} timervalue value in seconds to delay, false to execute now 212 | */ 213 | function setTimer(timervalue: number): string[] { 214 | const cmdarguments = []; 215 | 216 | if (process.platform === 'linux') { 217 | if (timervalue) { 218 | cmdarguments.push(timervalue.toString()); 219 | } else { 220 | cmdarguments.push('now'); 221 | } 222 | } 223 | 224 | if (process.platform === 'darwin') { 225 | if (timervalue) { 226 | let timeinminutes = Math.round(Number(timervalue) / 60); 227 | if (timeinminutes === 0) { 228 | timeinminutes = 1; // Minimum 1 minute 229 | } 230 | 231 | cmdarguments.push(`-t ${timeinminutes.toString()}`); 232 | } else { 233 | cmdarguments.push('now'); 234 | } 235 | } 236 | 237 | if (process.platform === 'win32') { 238 | if (timervalue) { 239 | cmdarguments.push(`-t ${timervalue.toString()}`); 240 | } else { 241 | cmdarguments.push('-t 0'); // Set to 0 because default is 20 seconds 242 | } 243 | } 244 | 245 | return cmdarguments; 246 | } 247 | 248 | /** 249 | * Execute command 250 | 251 | * @param {Boolean} debug show console results, not execute the command 252 | * @param {Boolean} quitapp quit app after send the command 253 | */ 254 | function executeCmd(cmd: string[], debug: boolean, quitapp: boolean): void { 255 | const finalcmd = cmd.join(' '); 256 | 257 | if (debug) { 258 | // Debug mode, print to console 259 | console.log(`Debug shutdown command: ${finalcmd}`); 260 | if (quitapp) { 261 | console.log('Now exit app...'); 262 | app.exit(0); 263 | } 264 | 265 | return; 266 | } 267 | 268 | // Execute the command 269 | cp.exec(finalcmd, err => { 270 | if (err) { 271 | console.error(err); 272 | return; 273 | } 274 | 275 | if (quitapp) { 276 | app.exit(0); 277 | } 278 | }); 279 | } 280 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "resolveJsonModule": true, 6 | "declaration": true, 7 | "pretty": true, 8 | "newLine": "lf", 9 | "stripInternal": true, 10 | "strict": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "noEmitOnError": true, 16 | // Disabled because of TS bugs: https://github.com/sindresorhus/tsconfig/issues/7 17 | // "useDefineForClassFields": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "skipLibCheck": true, 20 | "outDir": "dist", 21 | "target": "es2019", 22 | "lib": [ 23 | "es2019" 24 | ], 25 | "sourceMap": true 26 | }, 27 | "include": ["src/**/*.ts"], 28 | "exclude": [ 29 | "template/**/*.*", 30 | "node_modules" 31 | ] 32 | } --------------------------------------------------------------------------------