Skip to content

Commit e4182ca

Browse files
Fix Windows double-quotes bug
1 parent 5375576 commit e4182ca

File tree

7 files changed

+118
-56
lines changed

7 files changed

+118
-56
lines changed

manual-testing.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
* @author TheJaredWilcurt
44
*/
55

6-
const timeLabel = 'Executed in:';
6+
const timeLabel = 'Executed in';
77
console.time(timeLabel);
88

9-
let createDesktopShortcuts = require('./index.js');
9+
const createDesktopShortcuts = require('./index.js');
1010

1111
let success = createDesktopShortcuts({
1212
linux: {
@@ -25,7 +25,7 @@ let success = createDesktopShortcuts({
2525
icon: '..\\..\\..\\PortableApps\\Koa11y_v3.0.0\\package.nw\\_img\\fav.ico',
2626
filePath: 'C:\\PortableApps\\Koa11y_v3.0.0\\Koa11y.exe',
2727
outputPath: '%USERPROFILE%\\Desktop',
28-
arguments: '--my-argument -f \'other stuff\'',
28+
arguments: '--my-argument -f "other stuff"',
2929
windowMode: 'maximized',
3030
hotkey: 'ALT+CTRL+F'
3131
}

package-lock.json

Lines changed: 53 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "create-desktop-shortcuts",
33
"main": "index.js",
4-
"version": "1.8.0",
4+
"version": "1.9.0",
55
"description": "Easy API to create desktop shortcuts with Node",
66
"author": "The Jared Wilcurt",
77
"keywords": [
@@ -38,6 +38,7 @@
3838
"eslint-config-tjw-jsdoc": "^1.0.2",
3939
"eslint-plugin-jsdoc": "^39.3.2",
4040
"fs-extra": "8.1.0",
41+
"get-windows-shortcut-properties": "^1.1.0",
4142
"jest": "24.9.0",
4243
"mock-fs": "^5.1.2"
4344
},

src/library.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,13 @@ const library = {
161161
let windowMode = windowModes[options.windows.windowMode] || windowModes.normal;
162162
let hotkey = options.windows.hotkey || '';
163163

164-
// Double quotes must be escaped, VBScript uses double quotes as the escape character
165-
args = args.split('"').join('""');
166-
comment = comment.split('"').join('""');
167-
hotkey = hotkey.split('"').join('""');
164+
// Double quotes (") are used as an escape character in VBScript, and are stripped out of any arguments passed in
165+
function replaceDoubleQuotes (str) {
166+
return str.split('"').join('__DOUBLEQUOTE__');
167+
}
168+
args = replaceDoubleQuotes(args);
169+
comment = replaceDoubleQuotes(comment);
170+
hotkey = replaceDoubleQuotes(hotkey);
168171

169172
if (!icon) {
170173
if (

src/windows.vbs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@
55

66
option explicit
77

8+
' Double quotes are stripped out of arguments, so we replace them with this keyword, before passing them in
9+
' Then re-insert them in a way that VBScript permits, via Chr(34)
10+
Function replaceDoubleQuotes(str)
11+
replaceDoubleQuotes = Replace(str, "__DOUBLEQUOTE__", Chr(34))
12+
End Function
13+
814
dim strOutputPath, strFilePath, strArgs, strComment, strCwd, strIcon, strWindowMode, strHotkey
915
strOutputPath = Wscript.Arguments(0)
1016
strFilePath = Wscript.Arguments(1)
11-
strArgs = Wscript.Arguments(2)
12-
strComment = Wscript.Arguments(3)
17+
strArgs = replaceDoubleQuotes(Wscript.Arguments(2))
18+
strComment = replaceDoubleQuotes(Wscript.Arguments(3))
1319
strCwd = Wscript.Arguments(4)
1420
strIcon = Wscript.Arguments(5)
1521
strWindowMode = Wscript.Arguments(6)
16-
strHotkey = Wscript.Arguments(7)
22+
strHotkey = replaceDoubleQuotes(Wscript.Arguments(7))
1723

1824
sub createFile()
1925
dim objShell, objLink

tests/e2e.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ console.time(timeLabel);
88

99
const fs = require('fs-extra');
1010
const path = require('path');
11+
const getWindowsShortcutProperties = require('get-windows-shortcut-properties');
1112

1213
const createDesktopShortcuts = require('../index.js');
1314

@@ -21,6 +22,9 @@ let extension = extensions[process.platform] || '';
2122
const filePath = path.join(__dirname, 'src');
2223
const outputPath = path.join(__dirname, '__mocks__');
2324
const outputFile = path.join(__dirname, '__mocks__', 'src' + extension);
25+
const Arguments = '"test"';
26+
const hotkey = 'Ctrl+Shift+P';
27+
const comment = 'Some "very" good text.';
2428

2529
let success = createDesktopShortcuts({
2630
linux: {
@@ -34,7 +38,12 @@ let success = createDesktopShortcuts({
3438
},
3539
windows: {
3640
filePath,
37-
outputPath
41+
outputPath,
42+
hotkey,
43+
comment,
44+
arguments: Arguments,
45+
workingDirectory: outputPath,
46+
windowMode: 'maximized'
3847
}
3948
});
4049

@@ -77,7 +86,9 @@ function alert (pass, message) {
7786
console.log('\n ______________ ' + fill('_'));
7887
console.log('| |' + fill(' ') + '|');
7988
console.log('| E2E ' + state + ' | ' + message + ' |');
80-
console.timeEnd(timeLabel);
89+
if (process.platform !== 'win32') {
90+
console.timeEnd(timeLabel);
91+
}
8192
console.log('| |' + fill(' ') + '|');
8293
console.log(' ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ' + fill('¯') + '\n\n');
8394

@@ -89,6 +100,34 @@ function alert (pass, message) {
89100
if (success) {
90101
if (!fs.existsSync(outputFile)) {
91102
alert(false, 'Could not find desktop shortcut.');
103+
} else if (process.platform === 'win32') {
104+
// We need to log the Windows time now to be accurate, as the
105+
// getWindowsShortcutProperties step adds ~200-400ms that we don't care about
106+
console.log('\n ______________ __________________________');
107+
console.log('| | |');
108+
console.log('| WINDOWS TIME | |');
109+
console.timeEnd(timeLabel);
110+
console.log(' ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯' + '\n\n');
111+
// This is here to validate the VBS script outputted a shortcut as expected
112+
const outputProperties = getWindowsShortcutProperties.sync(outputFile)[0];
113+
const expected = {
114+
FullName: outputFile,
115+
Arguments: Arguments,
116+
Description: comment,
117+
Hotkey: hotkey,
118+
IconLocation: filePath + ',0',
119+
RelativePath: '',
120+
TargetPath: filePath,
121+
WindowStyle: '3',
122+
WorkingDirectory: outputPath
123+
};
124+
const windowsShortcutVerified = JSON.stringify(expected) === JSON.stringify(outputProperties);
125+
if (windowsShortcutVerified) {
126+
alert(true, 'Successly created and validated file.');
127+
} else {
128+
alert(false, 'Windows Shortcut properties mismatch');
129+
console.log({ expected, outputProperties });
130+
}
92131
} else {
93132
alert(true, 'Successly created and validated file.');
94133
}

tests/src/library.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ describe('library', () => {
475475
library.produceWindowsVBSPath(),
476476
'C:/Users/DUMMY/Desktop/file.lnk',
477477
'C:/file.ext',
478-
'-m ""Some text""',
478+
'-m __DOUBLEQUOTE__Some text__DOUBLEQUOTE__',
479479
'',
480480
'',
481481
'C:/file.ext',
@@ -505,7 +505,7 @@ describe('library', () => {
505505
'C:/Users/DUMMY/Desktop/file.lnk',
506506
'C:/file.ext',
507507
'',
508-
'Look at what ""I"" made.',
508+
'Look at what __DOUBLEQUOTE__I__DOUBLEQUOTE__ made.',
509509
'',
510510
'C:/file.ext',
511511
1,
@@ -538,7 +538,7 @@ describe('library', () => {
538538
'',
539539
'C:/file.ext',
540540
1,
541-
'CTRL+SHIFT+""'
541+
'CTRL+SHIFT+__DOUBLEQUOTE__'
542542
]
543543
);
544544
});

0 commit comments

Comments
 (0)