I am trying to have a Go program execute a vbscript that adds several registry values. The Go code that handles this is as follows:
err = exec.Command("cmd.exe", "/c", "registry.vbs").Run()
if err != nil {
fmt.Printf("Error: %s
", err.Error())
}
When I run my Go program and it gets to the part where it executes this vbscript absolutely nothing happens. The registry values are not changed and there are no errors. If I try to run the following command it works just fine:
cmd.exe /c C:\path\to\fileegistry.vbs
Things I have tried:
.Output()
instead of .Run()
and that resulted in the output equal to [ ]
Does anybody have any idea why this is happening?
Any direction would be greatly appreciated.
There are so many things that can go wrong in your scenario, that you should start simple:
(1) given a .vbs that does not try to change the registry (which Windows eagerly defends):
MsgBox "ThatsMe"
and the invocation
err := exec.Command("cmd.exe", "/c", "ThatMe.vbs").Run()
from an .exe in the same folder, I get a security alert: "Do you really want to open ThatsMe.vbs from the mapped network drive E:\". If I agree, the script is executed and the MsgBox appears. Your security settings may be so strict that you aren't even be asked.
(2) For the above invocation to work, the shell must know how to handle .VBS files. Your assoc/ftype settings may not provide this info. Then
err := exec.Command("wscript.exe", "ThatsMe.vbs").Run()
or
err := exec.Command("cscript.exe", "ThatsMe.vbs").Run()
should work - interestingly without the security warning.
(3) Instead of relying on the PATH and having/doing all files/work in the same folder, provinding full file specifications might be a good idea:
err := exec.Command(
"C:/WINDOWS/system32/wscript.exe",
"E:/trials/SoTrials/answers/10024850/go/ThatsMe.vbs").Run()
(4) If you can execute the humble ThatsMe.vbs, but your registry.vbs still fails, then you have to research who is allowed to see/change the parts of the registry you are interested in. Perhaps you have to invoke your executable as Administrator.
(5) While experimenting, I got fairly decent error messages from Go for the (un)intended nasty things I tried (using %comspec% instead of cmd.exe, bad file specs, ...). But trying to read a non-existing registry item caused a Windows Script Host error popup and no Go error. So your "absolutely nothing happens" diagnosis makes me wonder, whether Windows hides error messages from you. There are dark options like "Display a notification about every script error" in the IExplorer Advanced settings.
Try using Cscript.exe
instead of cmd.exe
.
Cscript.exe is a command-line version of the Windows Script Host that provides command-line options for setting script properties.
To get the output, use Output()
instead of Run()
.
Full example:
package main
import (
"fmt"
"os/exec"
)
func main() {
if out, err := exec.Command("Cscript.exe", "registry.vbs").Output(); err != nil {
fmt.Printf("Error: %s
", err)
} else {
fmt.Printf("%s
", out)
}
}
See "To run scripts using the command-line-based script host (Cscript.exe)" at TechNet.
Another approach is to make Windows run the default application for your .vbs
file. Typically, that will be wscript.exe
.