text: var path = require('path'),
    bin = path.join(__dirname, '..', 'bin'),
    exec = require('child_process').exec;
  
  var params = function (options, callback) {
    callback = callback || function () {
    };
    options = options || {};
    if (typeof options === 'function') {
      callback = options;
      options = {};
    }
    if (typeof options !== 'object') {
      throw 'Invalid options parameter.';
    }
    return {options: options, callback: callback};
  }
  
  module.exports = {
    /**
     * @method isElectron
     * Check if node windows is running inside electron application
     * @returns {boolean}
     */
    isElectron: function() {
      // Renderer process
      if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') {
        return true;
      }
  
      // Main process
      if (typeof process !== 'undefined' && typeof process.versions === 'object' && !!process.versions.electron) {
        return true;
      }
  
      // Detect the user agent when the `nodeIntegration` option is set to true
      if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) {
        return true;
      }
  
      return false;
    },
    /**
     * @method elevate
     * @member nodewindows
     * Elevate is similar to `sudo` on Linux/Mac. It attempts to elevate the privileges of the
     * current user to a local administrator. Using this does not require a password, but it
     * does require that the current user have administrative privileges. Without these
     * privileges, the command will fail with a `access denied` error.
     *
     * On systems with UAC enabled, this may prompt the user for permission to proceed:
     *
     * ![UAC Prompt](http://upload.wikimedia.org/wikipedia/en/5/51/Windows_7_UAC.png)
     *
     * **Syntax**:
     *
     * `elevate(cmd[,options,callback])`
     *
     * @param {String} cmd
     * The command to execute with elevated privileges. This can be any string that would be typed at the command line.
     * @param {Object} [options]
     * Any options that will be passed to `require('child_process').exec(cmd,<OPTIONS>,callback)`.
     * @param {Function} callback
     * The callback function passed to `require('child_process').exec(cmd,options,<CALLBACK>)`.
     */
    elevate: function (cmd, options, callback) {
      const electronPath = (() => path.join(__dirname.split('app.asar')[0], 'app.asar.unpacked', 'node_modules', 'node-windows', 'bin'))();
      let appPath = this.isElectron() ? electronPath : bin;
      const p = params(options, callback);
      exec(`"${path.join(appPath, 'elevate', 'elevate.cmd')}" ${cmd}`, p.options, p.callback);
    },
  
    /**
     * @method sudo
     * @member nodewindows
     * Sudo acts similarly to `sudo` on Linux/Mac. Unlike _elevate_, it requires a password, but it
     * will not prompt the user for permission to proceed. Like _elevate_, this
     * _still requires administrative privileges_ for the user, otherwise the command will fail.
     * The primary difference between this and _elevate()_ is the prompt.
     *
     * **Syntax**:
     *
     * `sudo(cmd,password[,options,callback])`
     *
     * @param {String} cmd
     * The command to execute with elevated privileges. This can be any string that would be typed at the command line.
     * @param {String} password
     * The password of the user
     * @param {Object} [options]
     * Any options that will be passed to `require('child_process').exec(cmd,<OPTIONS>,callback)`.
     * @param {Function} [callback]
     * The callback function passed to `require('child_process').exec(cmd,options,<CALLBACK>)`.
     */
    sudo: function (cmd, password, options, callback) {
      password = password || '';
      if (typeof password !== 'string') {
        callback = options;
        options = password;
        password = '';
      }
      var p = params(options, callback);
      exec(path.join(bin, 'sudowin', 'sudo.exe') + ' ' + (password !== '' ? '-p ' + password : '') + cmd, p.options, p.callback);
    }
  }
  