通过VBS隐藏PS窗口,返回码为

时间:2017-09-30 15:14:55

标签: powershell vbscript

我正在尝试使用VBScript帮助程序脚本在隐藏窗口中启动PowerShell脚本。我已经成功地做了一段时间,但现在我想添加一个返回代码,这使事情变得更复杂。 获取返回代码的常用方法是使用.Exec而不是.Run,​​但是您将失去隐藏命令窗口的能力。我找到了this thread,并根据这个和已知的工作strCMD,我尝试了

strCMD = strCMD & " > c:\out.txt"
objShell.Run strCMD, 0, True

但这不起作用。我出错的任何建议?或者有关更好地获取带有返回码的隐藏Powershell脚本的建议? FWIW,我必须针对PS 2.0。 :(

为完整起见,strCMD的值为

powershell -noLogo -noProfile -file "C:\Program Files\PragmaticPraxis\Resources\TestMessage.ps1" -message:"I'M ALIVE!!!" -message2:"Me too!"

而TestMessage.ps1只是

[CmdletBinding()]
param (
    [string]$message,
    [string]$message2
)

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $null
[System.Windows.Forms.MessageBox]::Show($message)
[System.Windows.Forms.MessageBox]::Show($message2)

编辑: 感谢omegastripes的链接,我正在尝试实现这个实现的更通用和PowerShell聚焦版本,使用一些代码重构来消除对函数的一次性调用和笨拙的强制退出。我有这个:

Option Explicit
Dim strCmd, strRes, objWnd, objParent, strSignature

If WScript.Arguments.Named.Exists("signature") Then 
    For Each objWnd In CreateObject("Shell.Application").Windows
        If IsObject(objWnd.getProperty(WScript.Arguments.Named("signature"))) Then Exit For
    Next
    Set objParent = objWnd.getProperty(WScript.Arguments.Named("signature"))

    objWnd.Quit
    objParent.strRes = CreateObject("WScript.Shell").Exec(objParent.strCmd).StdOut.ReadAll()
Else
    strCmd = "powershell.exe -noLogo -noProfile -executionPolicy bypass -file ""\\Mac\Px\Support\Px Tools\Dev 3.3.#\_Spikes\TestMessage.ps1"""
    strSignature = Left(CreateObject("Scriptlet.TypeLib").Guid, 38)
    GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}").putProperty strSignature, Me
    CreateObject("WScript.Shell").Run ("""" & Replace(LCase(WScript.FullName), "wscript", "cscript") & """ //nologo """ & WScript.ScriptFullName & """ ""/signature:" & strSignature & """"), 0, True

    WScript.Echo strRes
End If

反过来调用此PS1

try {
    [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $null
    [System.Windows.Forms.MessageBox]::Show("Message test!") > $null
    Write-Host "Success"
} catch {
    Write-Host "Failure"
}

这是因为它确实运行PS1,它是隐藏的,但是我无法获得结果。我尝试过Return,Write-Output和Write-Host,没有人将PS1的结果发送回VBS。我在传递参数时也遇到了一些问题,而且我真的不喜欢内部强制退出的For Each循环,但这很精简。更大的问题是如何始终从PS1获得结果。

1 个答案:

答案 0 :(得分:0)

您的powershell脚本需要通过以下方式返回退出代码

Exit <int>

您在VBS中WScript.Shell的Run方法将返回此代码,因此您需要保存它。

Set WshShell = WScript.CreateObject("WScript.Shell")
Result = WshShell.Run(...

因此Result现在包含退出代码,因此您现在可以使用它或再次返回它并退出该过程。

WScript.Quit(Result)