1

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\n", 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\file\registry.vbs

Things I have tried:

  • Add file path in the Go program
  • Run the Go program as an administrator
  • I tried using .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.

Peter
  • 3,144
  • 11
  • 37
  • 56

3 Answers3

5

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.

Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
  • Turns out using `cscript.exe` combined with a function I found at http://stackoverflow.com/questions/14763625/i-have-issue-with-shell-regwrite-on-windows-8 to prompt UAC resolved the issue. Thanks for the help. – Peter Dec 03 '13 at 17:20
3

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\n", err)
    } else {
        fmt.Printf("%s\n", out)
    }
}

See "To run scripts using the command-line-based script host (Cscript.exe)" at TechNet.

Intermernet
  • 18,604
  • 4
  • 49
  • 61
0

Another approach is to make Windows run the default application for your .vbs file. Typically, that will be wscript.exe.

Community
  • 1
  • 1
kostix
  • 51,517
  • 14
  • 93
  • 176