How do i prevent a VBScript from running standalone?
Asked Answered
U

4

3

I'm doing a mash between VbScript and CMD, i can call the VBScript easily with

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

But I need to disable the feature of users clicking on the VBScript and calling all sorts of errors, rather than it being called through a batch file.

My first attempt was a mess of setting a variable into a text file before i ran cscript.exe and use error handling in VBScript to tell if that variable could be collected, but it added too much time to the script.

Does VBScript have a way to tell whether it was started by CMD, or simply by double clicking, and able to act accordingly?

Uhhuh answered 16/12, 2015 at 17:43 Comment(5)
Even if you incorporated such a check, what would prevent your users from putting a line cscript "C:\path\to\your\script.vbs" in a batch file and double-clicking that batch file? What is the actual problem you're trying to solve here?Inducement
giving it a parametercheck? Double click = no Parameter. (don't speak VBS - in Batch it would be something like if "%1"=="" ExitCandlemaker
If would probably be easiest to create a batch/vbscript hybrid script so that there is only script.Silvia
In such a case, it would be simpler to translate the VBScript code into JScript (it can be done with no problems), and then create a Batch/JScript hybrid in a very simple way. See: #15168242Troubadour
Sorry for the late comment. This is to prevent less 'code savvy' users from launching the file and complaining about 'errors' in my code. "Jason Faulkner" gave an adequate solution.Uhhuh
O
4

Here is a simple function, detecting the parent process caption. You can check if the process was started by CMD shell (the caption is cmd.exe) or by double-click (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

In the context of your question another method allowing to pass parameters from CMD shell process to WSH script child process may be useful. It uses environment variable and WScript.Shell object. Consider the below example.

There is code for task.cmd file:

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

And for task.vbs file:

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

I have got the output as follows:

cmd shell output

wsh output

Note, process environment variables are accessible for child processes only.

Oro answered 16/12, 2015 at 20:33 Comment(3)
I've only known CMD till now, VBScript is blowing my mind with how it works, but its speed and reliability is worth it. Aka, your answer confuses me but looks official. Thanks for the different approach to an answer!Uhhuh
@Arescet I added another method of passing parameters from CMD shell process to WSH script child process.Oro
wow, this whole time i've been echo'ing the variables into a named file, retrieving them with vbs 'read' commands, and then proccessing them. This whole time i could've just passed them by reference, and even check the launch state with them...thanks!Uhhuh
R
1

One way is for your VBS file to check for the presence of parameters and if they do not exist then stop the execution.

In your VBS script:

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

When you call your VBS file, just passing any parameter will satisfy the condition:

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"

This will not stop people from running it manually (with a parameter) or creating a shortcut which has a parameter. It would only really stop running the VBS directly (as a parameter will not be passed).

Relinquish answered 16/12, 2015 at 19:56 Comment(1)
Thanks for the simple answer. This whole time i didnt know VBScript and CMD were able to pass variables like referencing in call. Now to make 1/2 of my code obsolete...Uhhuh
J
0

When you double click on a .vbs file, the action is determined by the following registry key:

  • Computer\HKEY_CLASSES_ROOT\VBSFile\Shell\Open\Command

If you were to change the key, you will be changing the double click action, but you will not be affecting your ability to launch the command explicitly via invoking cscript.exe directly.

Jueta answered 16/12, 2015 at 23:0 Comment(0)
N
0

If the bat file will keep the cmd.exe open while the vbs file runs, you can try to detect the cmd process inside the vbs file to continue execution.

Put this at the start of your vbs file:

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
Nombril answered 16/12, 2015 at 23:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.