Как я могу предотвратить автономный запуск VBScript?
Я делаю смесь между VbScript и CMD, я могу легко вызвать VBScript с
cscript.exe //NoLogo "%~dp0TASK.vbs" >>"%~dp0output.txt"
Но мне нужно отключить функцию пользователей, щелкающих по VBScript и вызывающих всевозможные ошибки, а не вызываемых через командный файл.
Моя первая попытка была путаница установки переменной в текстовый файл, прежде чем я побежал cscript.exe
и использовать обработку ошибок в VBScript, чтобы определить, может ли эта переменная быть собрана, но это добавило слишком много времени сценарию.
Есть ли у VBScript способ узнать, был ли он запущен CMD или просто двойным щелчком, и способен ли он действовать соответственно?
4 ответа
Вот простая функция, определяющая заголовок родительского процесса. Вы можете проверить, был ли процесс запущен оболочкой CMD (заголовок 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 в дочерний процесс сценария WSH. Он использует переменную окружения и WScript.Shell
объект. Рассмотрим приведенный ниже пример.
Есть код для task.cmd
файл:
set myvar=myvalue
wscript "%~dp0task.vbs"
И для task.vbs
файл:
WScript.Echo CreateObject("WScript.Shell").Environment("process").Item("myvar")
Я получил вывод следующим образом:
Обратите внимание, что переменные среды процесса доступны только для дочерних процессов.
Один из способов - ваш 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 напрямую (так как параметр не будет передан).
Когда вы дважды щелкните на .vbs
файл, действие определяется следующим ключом реестра:
- Компьютер \HKEY_CLASSES_ROOT\VBSFile\Shell\Open\Command
Если вы измените ключ, вы измените действие двойного щелчка, но это не повлияет на вашу способность явно запускать команду с помощью вызова cscript.exe
непосредственно.
Если файл bat будет держать cmd.exe открытым во время работы файла vbs, вы можете попытаться обнаружить процесс cmd внутри файла vbs, чтобы продолжить выполнение.
Поместите это в начало вашего файла 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