我在VbScript和CMD之间进行混搭,我可以轻松调用VBScript
cscript.exe //NoLogo "%~dp0TASK.vbs" >>"%~dp0output.txt"
但是我需要禁用用户点击VBScript并调用各种错误的功能,而不是通过批处理文件调用它。
我的第一次尝试是在运行cscript.exe
之前将变量设置为文本文件,并在VBScript中使用错误处理来判断是否可以收集该变量,但是它为脚本添加了太多时间。
VBScript是否有办法判断它是由CMD启动,还是只是双击,并能够相应地采取行动?
答案 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")
我的输出如下:
请注意,只有子进程可以访问进程环境变量。
答案 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
文件时,操作由以下注册表项确定:
如果您要更改密钥,您将更改双击操作,但不会影响您通过直接调用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