Execute a vbscript in Go

huangapple go评论92阅读模式
英文:

Execute a vbscript in Go

问题

我正在尝试让一个Go程序执行一个添加多个注册表值的vbscript脚本。处理这个任务的Go代码如下:

err = exec.Command("cmd.exe", "/c", "registry.vbs").Run()
if err != nil {
    fmt.Printf("Error: %s\n", err.Error())
}

当我运行这个Go程序并执行这个vbscript脚本时,什么都没有发生。注册表的值没有改变,也没有出现错误。但是,如果我尝试运行以下命令,它可以正常工作:

cmd.exe /c C:\path\to\file\registry.vbs

我尝试过的解决方法:

  • 在Go程序中添加文件路径
  • 以管理员身份运行Go程序
  • 尝试使用.Output()代替.Run(),但输出结果为空数组[ ]

有人知道为什么会出现这种情况吗?

非常感谢任何指导!

英文:

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.

答案1

得分: 5

在你的情况下,有很多可能出错的地方,所以你应该从简单的开始:

(1)给定一个不尝试更改注册表的.vbs文件(Windows会积极防御):

MsgBox "ThatsMe"

并且调用

err := exec.Command("cmd.exe", "/c", "ThatMe.vbs").Run()

从相同文件夹中的.exe文件中,我会收到一个安全警告:“您真的要打开来自映射网络驱动器E:\的ThatsMe.vbs吗?”如果我同意,脚本将被执行并出现MsgBox。您的安全设置可能非常严格,以至于您甚至不会被询问。

(2)为了使上述调用起作用,shell必须知道如何处理.VBS文件。您的assoc/ftype设置可能没有提供此信息。然后

err := exec.Command("wscript.exe", "ThatsMe.vbs").Run()

err := exec.Command("cscript.exe", "ThatsMe.vbs").Run()

应该可以工作-有趣的是没有安全警告。

(3)不要依赖于PATH,并且在同一文件夹中拥有/执行所有文件/工作,提供完整的文件规范可能是一个好主意:

err := exec.Command(
    "C:/WINDOWS/system32/wscript.exe",
    "E:/trials/SoTrials/answers/10024850/go/ThatsMe.vbs").Run()

(4)如果您可以执行简单的ThatsMe.vbs,但是您的registry.vbs仍然失败,则必须研究谁被允许查看/更改您感兴趣的注册表部分。也许您必须以管理员身份调用可执行文件。

(5)在实验过程中,对于我尝试的(不)意外的恶意操作(使用%comspec%而不是cmd.exe,错误的文件规范等),我得到了相当不错的错误消息。但是尝试读取不存在的注册表项会导致Windows脚本宿主错误弹出窗口和没有Go错误。因此,您的“绝对没有任何反应”的诊断让我怀疑Windows是否隐藏了错误消息。在Internet Explorer的高级设置中,有“显示有关每个脚本错误的通知”等黑暗选项。

英文:

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.

答案2

得分: 3

尝试使用Cscript.exe代替cmd.exe

> Cscript.exe是Windows脚本宿主的命令行版本,提供了用于设置脚本属性的命令行选项。

要获取输出,请使用Output()而不是Run()

完整示例:

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	if out, err := exec.Command("Cscript.exe", "registry.vbs").Output(); err != nil {
		fmt.Printf("错误:%s\n", err)
	} else {
		fmt.Printf("%s\n", out)
	}
}

请参阅TechNet上的“使用基于命令行的脚本宿主(Cscript.exe)运行脚本”

英文:

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.

答案3

得分: 0

另一种方法是让Windows运行你的.vbs文件的默认应用程序。通常情况下,这将是wscript.exe

英文:

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

huangapple
  • 本文由 发表于 2013年12月3日 17:41:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/20347549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定