TL;DR: const spawn=require('child_process').spawn; spawn('powershell.exe', ['D:/Dev/My Bot/test.ps1']);
doesn’t work
Hello,
I am using discord.js to make a bot, i want a command to execute a powershell script when it’s called, the command handling, registering works fine, but the execution of the script isn’t successful.
Here is the code of my command:
const { SlashCommandBuilder } = require('discord.js');
const spawn = require('child_process').spawn;
const authorizedUsers = ['...', '...'];
module.exports = {
data: new SlashCommandBuilder()
.setName('start_server')
.setDescription('Start the minecraft modded server.'),
async execute(interaction) {
// If the user is authorized to run the command
if (authorizedUsers.includes(interaction.user.id)) {
console.log('Starting minecraft server');
spawn('powershell.exe', ['D:/Dev/My Bot/test.ps1']);
console.log('Minecraft server started !');
await interaction.reply('Minecraft server started !');
}
else {
await interaction.reply('You can't use this command');
}
},
};
The two messages are correctly sent in the console, the bot also replies to my message in discord, but the script isn’t executed…
Can you help me with this ?
2
Answers
Here is the code that worked for me
Thank you for your help !
To explain the original problem:
This fails, because the default parameter of
powershell.exe
, the Windows PowerShell CLI, is-Command
,[1] which means that, translated to a process command line, your call is equivalent to:This is broken, because
-Command
strips the"
chars. during initial command-line parsing and then interprets the result as PowerShell code, resulting in a – broken – attempt to executeD:/Dev/My Bot/test.ps1
(the lack of quoting makes this two arguments).The simple – and preferable for script-file invocation – solution is to use the
-File
parameter, where no additional interpretation of the CLI arguments is performed:The way to express the above via a
spawn
call is:Note that there is no need for embedded quoting, because
spawn
will ensure that'D:/Dev/My Bot/test.ps1'
is placed as"D:/Dev/My Bot/test.ps1"
on thepowershell.exe
process command line.By contrast, if you did want to solve this via (implied)
-Command
, you would need embedded quoting, and also&
, PowerShell’s call operator, which is needed whenever a command to execute is quoted.See also:
-File
vs.-Command
in PowerShell CLI calls.[1] By contrast,
pwsh.exe
, the PowerShell (Core) CLI, now defaults to-File
.