如何防止VBScript独立运行?

时间:2015-12-16 17:43:01

标签: batch-file vbscript cmd wsh

我在VbScript和CMD之间进行混搭,我可以轻松调用VBScript

cscript.exe //NoLogo "%~dp0TASK.vbs" >>"%~dp0output.txt"

但是我需要禁用用户点击VBScript并调用各种错误的功能,而不是通过批处理文件调用它。

我的第一次尝试是在运行cscript.exe之前将变量设置为文本文件,并在VBScript中使用错误处理来判断是否可以收集该变量,但是它为脚本添加了太多时间。

VBScript是否有办法判断它是由CMD启动,还是只是双击,并能够相应地采取行动?

4 个答案:

答案 0 :(得分:4)

这是一个简单的函数,检测父进程标题。您可以检查进程是由CMD shell启动的(标题是cmd.exe)还是双击(explorer.exe):

If LCase(GetParentProcessCaption()) <> "cmd.exe" Then WScript.Quit

' the rest part of your code here

Function GetParentProcessCaption()
    With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & CreateObject("WScript.Shell").Exec("rundll32 kernel32,Sleep").ProcessId & "'")
        With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & .ParentProcessId & "'")
            With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & .ParentProcessId & "'")
                GetParentProcessCaption = .Caption
            End With
        End With
        .Terminate
    End With
End Function

在您的问题的上下文中,允许将参数从CMD shell进程传递到WSH脚本子进程的另一种方法可能很有用。它使用环境变量和WScript.Shell对象。请考虑以下示例。

task.cmd文件的代码:

set myvar=myvalue
wscript "%~dp0task.vbs"

对于task.vbs文件:

WScript.Echo CreateObject("WScript.Shell").Environment("process").Item("myvar")

我的输出如下:

cmd shell output

wsh output

请注意,只有子进程可以访问进程环境变量。

答案 1 :(得分:1)

一种方法是让您的VBS文件检查是否存在参数,如果它们不存在则停止执行。

在您的VBS脚本中:

If WScript.Arguments.Count = 0 then
    ' No parameters provided. Can stop here.
End If

当您调用VBS文件时,只需传递任何参数即可满足条件:

REM This will work.
cscript.exe //NoLogo "%~dp0TASK.vbs" "hello world"

REM So will this.
cscript.exe //NoLogo "%~dp0TASK.vbs" 1 2 3 4

REM This will not.
cscript.exe //NoLogo "%~dp0TASK.vbs"

这不会阻止人们手动(使用参数)或创建具有参数的快捷方式。它只会直接停止运行VBS(因为参数不会被传递)。

答案 2 :(得分:0)

双击.vbs文件时,操作由以下注册表项确定:

  • 计算机\ HKEY_CLASSES_ROOT \ VBSFile \壳牌\打开\命令

如果您要更改密钥,您将更改双击操作,但不会影响您通过直接调用cscript.exe显式启动命令的能力。

答案 3 :(得分:0)

如果bat文件在vbs文件运行时保持cmd.exe打开,您可以尝试检测vbs文件中的cmd进程以继续执行。

将其放在vbs文件的开头:

Set shell = CreateObject("WScript.Shell")
list_str = shell.Exec("tasklist").stdOut.ReadAll 'get a list of processes by calling the windows program 'tasklist.exe'
If InStr(list_str, "cmd.exe") = 0 Then WScript.Quit 'quit if process is not found