skip to Main Content

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


  1. Chosen as BEST ANSWER

    Here is the code that worked for me

    const { exec } = require('child_process');
    
    const scriptPath = '"D:\PATH_TO_FOLDER_WHERE_SCRIPT_IS_LOCATED\start.ps1';
    const command = `powershell.exe -File ${scriptPath}`;
    
    exec(command, (error) => {
        if (error) {
            console.error(`Error executing PowerShell script: ${error}`);
            return;
        }
    
        console.log('Script executed successfully!');
    });
    

    Thank you for your help !


  2. To explain the original problem:

    spawn('powershell.exe', ['D:/Dev/My Bot/test.ps1'])

    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:

    # !! BROKEN, due to -Command
    powershell.exe -Command "D:/Dev/My Bot/test.ps1"
    

    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 execute
    D:/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:

    # OK, due to -File
    powershell.exe -File "D:/Dev/My Bot/test.ps1"
    

    The way to express the above via a spawn call is:

    spawn('powershell.exe', ['-File', 'D:/Dev/My Bot/test.ps1'])
    

    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 the powershell.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.

    # Translates to:
    #   powershell.exe "& "D:/Dev/My Bot/test.ps1""
    spawn('powershell.exe', ['& "D:/Dev/My Bot/test.ps1"'])
    

    See also:

    • Guidance on when to use -File vs. -Command in PowerShell CLI calls.

    [1] By contrast, pwsh.exe, the PowerShell (Core) CLI, now defaults to -File.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search