Как я могу предотвратить автономный запуск 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")

Я получил вывод следующим образом:

вывод оболочки cmd

вывод wsh

Обратите внимание, что переменные среды процесса доступны только для дочерних процессов.

Один из способов - ваш 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
Другие вопросы по тегам