Skip to content

Commit

Permalink
Workaround issue jorangreef#97 by copying cmd.exe into the temporary …
Browse files Browse the repository at this point in the history
…folder and running it from here
  • Loading branch information
zvin committed Sep 11, 2020
1 parent c3cc31a commit 81cab70
Showing 1 changed file with 32 additions and 13 deletions.
45 changes: 32 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,18 @@ function Windows(instance, callback) {
WindowsWriteCommandScript(instance,
function(error) {
if (error) return end(error);
WindowsElevate(instance,
function(error, stdout, stderr) {
if (error) return end(error, stdout, stderr);
WindowsWaitForStatus(instance,
function(error) {
if (error) return end(error);
WindowsResult(instance, end);
WindowsCopyCmd(instance,
function(error) {
if (error) return end(error);
WindowsElevate(instance,
function(error, stdout, stderr) {
if (error) return end(error, stdout, stderr);
WindowsWaitForStatus(instance,
function(error) {
if (error) return end(error);
WindowsResult(instance, end);
}
);
}
);
}
Expand All @@ -509,22 +514,36 @@ function Windows(instance, callback) {
);
}

function WindowsCopyCmd(instance, end) {
// Work around https://github.com/jorangreef/sudo-prompt/issues/97
// Powershell can't properly escape amperstands in paths.
// We work around this by copying cmd.exe in our temporary folder and running
// it from here (see WindowsElevate below).
// That way, we don't have to pass the path containing the amperstand at all.
// A symlink would probably work too but you have to be an administrator in
// order to create symlinks on Windows.
Node.fs.copyFile(
Node.path.join(Node.process.env.SystemRoot, 'System32', 'cmd.exe'),
Node.path.join(instance.path, 'cmd.exe'),
end
);
}

function WindowsElevate(instance, end) {
// We used to use this for executing elevate.vbs:
// var command = 'cscript.exe //NoLogo "' + instance.pathElevate + '"';
var command = [];
command.push('powershell.exe');
command.push('Start-Process');
command.push('-FilePath');
// Escape characters for cmd using double quotes:
// Escape characters for PowerShell using single quotes:
// Escape single quotes for PowerShell using backtick:
// See: https://ss64.com/ps/syntax-esc.html
command.push('"\'' + instance.pathExecute.replace(/'/g, "`'") + '\'"');
// Node.path.join('.', 'cmd.exe') would return 'cmd.exe'
command.push(['.', 'cmd.exe'].join(Node.path.sep));
command.push('-ArgumentList');
command.push('"/C","execute.bat"');
command.push('-WindowStyle hidden');
command.push('-Verb runAs');
command = command.join(' ');
var child = Node.child.exec(command, { encoding: 'utf-8' },
var child = Node.child.exec(command, { encoding: 'utf-8', cwd: instance.path },
function(error, stdout, stderr) {
// We used to return PERMISSION_DENIED only for error messages containing
// the string 'canceled by the user'. However, Windows internationalizes
Expand Down

0 comments on commit 81cab70

Please sign in to comment.