kessler / node-regedit

Read, Write, List and do all sorts of funky stuff to the windows registry using node.js and windows script host
MIT License
279 stars 45 forks source link

cscript.exe cannot be found when using with electron-forge #123

Open GrosuCristi opened 1 week ago

GrosuCristi commented 1 week ago

There is an internal bug that happens inside regedit when using it together with electron forge. I posted a question on stackoverflow about this problem here.

Recreating the issue

To recreate this issue you will have to make an electron-forge project first. In my case I used electron-forge with the webpack plugin. Use the command below to create the project: npm init electron-app@latest my-new-app -- --template=webpack of course install regedit too: npm i regedit Then you will have to add some code to the main process file to use any method from regedit that will access the registry. Also make sure to have all .vbs files in your project somewhere. In this example i put them inside "/PROJECT_DIR/resources/vbs/"

// other imports...
const regedit = require('regedit')
regedit.setExternalVBSLocation(path.join(process.cwd(), "resources/vbs");
regedit.list(['HKCU\\SOFTWARE', 'HKLM\\SOFTWARE', 'HKCU\\IM_FAKE_THEREFOR_I_DONT_EXIST'], function(err, result) {
    if (err) console.log(err)
    else console.log(result)
})

// the rest of the main process code remains below...

now start the app: npm start

You should now get an error that csript.exe cannot be found.

Some useful information that I found

So I digged inside the code of the regedit package and found that a weird thing happens inside the baseCommand method. This is how it is defined:

function baseCommand(cmd, arch) {
    let scriptPath

    // test undefined, null and empty string
    if (externalVBSFolderLocation && typeof(externalVBSFolderLocation) === 'string') {
        scriptPath = externalVBSFolderLocation
    } else {
        scriptPath = path.join(__dirname, 'vbs')
    }

    return ['//Nologo', path.join(scriptPath, cmd), arch]
}

As we set the external vbs location the if condition should be truthy. In addition, scriptPath should take the value of externalVBSFolderLocation. But in the end, it doesn't even though the code inside the if block executes because the condition is true. Here is how to prove it by adding some console logs:

function baseCommand(cmd, arch) {
    let scriptPath

    // test undefined, null and empty string
    if (externalVBSFolderLocation && typeof(externalVBSFolderLocation) === 'string') {
        scriptPath = externalVBSFolderLocation
        console.log(scriptPath) // Logs: "C:\Users\alex\Desktop\projectdir\resources\vbs\"
    } else {
        console.log("I got executed") //  This will not log
        scriptPath = path.join(__dirname, 'vbs')
    }
    console.log(scriptPath) // Logs "undefinedvbs" which is very strange
    return ['//Nologo', path.join(scriptPath, cmd), arch]
}

Now by restarting the project you should see some logs to the console that match those from baseCommand.

A quick fix

Here is a workaround that i used:

function baseCommand(cmd, arch) {
    return ['//Nologo', path.join(externalVBSFolderLocation, cmd), arch]
}

But i think this problem should be fixed in a more proffessional manner.