我正试图让Go程序执行一个添加了几个registry值的vbscript。 Go代码处理这个如下:
err = exec.Command("cmd.exe", "/c", "registry.vbs").Run() if err != nil { fmt.Printf("Error: %s\n", err.Error()) }
当我运行我的Go程序,它到达它执行这个VBScript的部分绝对没有任何反应。 registry值不会更改,并且没有错误。 如果我尝试运行下面的命令,它工作得很好:
cmd.exe /c C:\path\to\file\registry.vbs
我已经尝试过的事情:
.Output()
而不是.Run()
并导致输出等于[ ]
有谁知道为什么会发生这种情况?
任何方向将不胜感激。
在你的场景中有太多东西可能出错,你应该从简单的开始:
(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)在尝试的时候,我从Go上得到了相当不错的错误信息,用于(我)尝试的(un)意图不好的事情(使用%comspec%而不是cmd.exe,错误的文件规格等等)。 但试图读取不存在的注册表项导致Windows脚本宿主错误弹出窗口,并没有出现错误。 所以你的“绝对没有任何反应”的诊断让我怀疑,Windows是否隐藏了你的错误信息。 在“IExplorer高级”设置中有“显示关于每个脚本错误的通知”等黑暗选项。
尝试使用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("Error: %s\n", err) } else { fmt.Printf("%s\n", out) } }
请参阅TechNet上的“使用基于命令行的脚本宿主(Cscript.exe)运行脚本” 。
另一种方法是使Windows 运行您的.vbs
文件的默认应用程序 。 通常,这将是wscript.exe
。