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?
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:
Note, process environment variables are accessible for child processes only.
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).
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.
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
Related
I am trying to control Spotify volume from inside a game without switching windows. To do this I did the following:
A. Found nircmd.exe from NirSoft that can control individual program volumes in Windows
B. Wrote a batch to execute the command
C. Wrote this .vbs script to hook into the batch silently:
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run chr(34) & "Spotify App Volume Up.bat" & Chr(34), 0
Set WshShell = Nothing
^
Using this .vbs snippet to accomplish silent run is really popular. This works when I click the .vbs myself. The problem I have is I need a way to execute this from another program. When I try to execute from any hotkey program or something like AutoHotKey it gives me this error:
ActiveX Component cannot create object 'WScript.Shell' Code: 800a01ad
I tried setting security of all involved files to everyone, full control. It did not help. It seems to me that Windows is trying to protect me by preventing scripts from initializing by other programs. Any suggestions? Otherwise does someone know how to execute this silently with another method?
EDIT:
AutoHotKey's run command will do this:
run "mybat.bat",, Hide
However, does anyone know how to get around this behavior with .vbs? I am curious.
I believe all your scripts, vbscript and your batch file can potentially be written natively in Ahk, but here's how I'd launch your vb script.
x:: ; press x
sc := ComObjCreate("ScriptControl")
sc.Language := "VBScript"
script =
(
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run chr(34) & "Spotify App Volume Up.bat" & Chr(34), 0
Set WshShell = Nothing
)
sc.ExecuteStatement(script)
return
I'm trying to launch 2 VBS and 1 BATCH script all at the same time. So I would have 3 lines of code launching 3 things all at the same time without one having to wait for the other to finish.
I've tried a BATCH script to launch these 3 but I can't get it to work without it waiting for one process before it moves onto the next line of code.
I tried a VBS to launch these 3 but it tells me it can't find the file location if I have more than one line.
So which one would be more effective (or what type of any code would be most effective) and what would be the code to launch all 3?
start "" cscript vbscript1.vbs
start "" cscript vbscript2.vbs
start "" batchFile.bat
Start command will start a process without waiting for its finish.
In vbscript you can do something like that :
Option Explicit
Dim Vbsfile1,Vbsfile2,Batchfile
Vbsfile1 = "C:\HackooTest\Nouveau dossier\ConnectJob.vbs"
Vbsfile2 = "C:\HackooTest\Nouveau dossier\Calc.vbs"
Batchfile = "C:\HackooTest\Nouveau dossier\toto1.bat"
Call Launch(Vbsfile1)
Call Launch(Vbsfile2)
Call Launch(Batchfile)
'********************************************
Sub Launch(MyProgram)
Dim ws,Result
Set ws = CreateObject("wscript.Shell")
Result = ws.run(DblQuote(MyProgram),1,False)
End Sub
'********************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'********************************************
I have a legacy application which doesn't support utilizing the default applications defined in windows which requires that I specify a specific an executable for a file format to be opened within the application. Since Microsoft no longer includes MODI with Office by default I have been looking at using launching Windows Picture Viewer for .TIF, .TIFF, & .BMP files since it is built into Windows; however Microsoft does not have a direct executable for Windows Picture Viewer which can be called forcing me to create a script which executes the command which calls for Windows Picture Viewer to execute. After research the only way I have been able to call the application to open a specific file is by creating a batch file such as below:
GIFTS.BAT
rundll32.exe C:\WINDOWS\system32\shimgvw.dll,ImageView_Fullscreen %~1
If I execute the above code such as GIFTS.BAT "C:\Example Directory\Sample File.tif" from a command prompt or from the application launches and the Sample File.tif opens without a problem; however a command prompt opens along with the file when launching from the application.
Upon which I tried to create a vbscript to hide the batch file from executing however I can't seem to pass my argument if the argument has a "space" within the argument.
GIFTS.VBS
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run """C:\GIFTS.BAT"" " & WScript.Arguments.Item(0), 0
Set WshShell = Nothing
If I try to execute the VBScript from a command prompt such as GIFTS.VBS "C:\Example Directory\Sample File.tif" the application never launches and the command prompt returns no message or error. If I simplify the execute command (removing spaces to GIFTS.VBS "C:\Sample_File.tif" the application launches as well as the file Sample_File.tif is displayed and there is no command prompt displayed when the application executes the VBScript.
My question is how can I pass an argument into the VBS script that in return passes the the batch file when the argument contains spaces (which there is always going to be spaces since the argument will be a file name and path)?
There might be an easier approach to what I want to accomplish; however I am looking for a solution that Windows 7 - 8.1 can utilize with no additional software to install or manage on each workstation. The batch files works great I just need to be able to hide the command prompt that opens along with the application as my end users won't know what to do with it.
Thanks!
Sometimes, nested levels of escaping characters requires intimate knowledge of the undocumented behavior of CMD or some voodoo. Another way to attack the problem is to guarantee that you won't have any spaces in the name of the file. Windows has a concept of a short path (no spaces or special chars) for which every existing file has a unique one.
Here's a modified version of your program for which invoked subcommand doesn't need quotes around the file name.
Set WshShell = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set fsoFile = fso.GetFile(WScript.Arguments.Item(0))
WshShell.Run """c:\GIFTS.BAT"" " & fsoFile.ShortPath, 0
Set WshShell = Nothing
You may wish to add your own error checking. The specified file must exist in order for the GetFile() command to succeed.
I have a VBScript that is supposed to run a .bat or .vbs file, but it doesn't work!
It comes up with an error saying that the file could not be found, whether i put in a file path or not (it shouldn't matter anyway I think because it's in the same directory).
So my question is, how do I start a .bat file (or even better, a .vbs file) from within a VBScript?
The relevant code is bellow:
'*******This is the start of my open command that doesn't work*******
Do
If Hour(Now) >= 9 And Hour(Now) <= 18 And Minute(Now) = 34 And Second(Now) = 59 Then
Dim shell
Set shell = CreateObject("WScript.Shell")
shell.Run "F:\\EAS\Volume Up.vbs"
Set shell = Nothing
MsgBox "My De-bug Message Box which doesn' even get to open"
WScript.Sleep 2000
Set WshShell = CreateObject("WScript.Shell")
music = "C:\...\MYFILE.wav"
WshShell.Run "wmplayer """ & music & """", 0, True
WScript.Quit 1
Else
'*******This is the end*******
So what am I doing wrong? Is it the wrong way to open it? What should I put instead?
It would be good to see the contents of the .BAT File.
Your code seems fine as I am able to run the below script on my machine:
dim shell
set shell=createobject("wscript.shell")
shell.run "tester.bat"
You may not see what the .BAT File is doing as it happens so quickly, as a tester add the following command to the end of your .BAT Script:
pause
Then you will see the command prompt open. As per my VB code above, the .BAT file contents are below:
#echo OFF
#echo %time%
pause
This will show you the current time and then pause, leaving the command prompt open. Give this a go as a tester as it works fine for me.
putting triple quotes (as suggested by ToThePoint) around the path solved my vbs file error, where it was failed to find the file on specified path as file path was having spaces, like
D:\Main\My text Files\abc.txt.
thanks :)
The only thing i can think of is that it must be a typo in the file name.
Can you ensure the file name is spelled correct?
Or else please post the exact error you get.
This is sort of a follow-up to my question earlier (link).
To test things out I made this simple batch file to ensure the Task Scheduler was properly executing the batch file:
cd "C:\Users\user\Desktop"
echo. 2>test.txt
So after the test.txt document is created on the desktop, the batch file should end but it continues to run:
Is there a way, either at the end of the batch file or a setting in the Task's Properties, to ensure that the cmd process quits?
Thanks!
I ran into the exact same problem. However, I felt duped when I read what Trevor778 wrote in this post:
I had the same problem - the task worked but the status kept showing Running. One simple thing to try is click on the Task Scheduler Library in the left column. Click Action/Refresh. Presto. Status changed to Ready. That's all it was for me, the task ran fine, just the status didn't update. Hope this helps.
ref: https://social.technet.microsoft.com/Forums/en-US/2f6dc29c-3b8b-45f5-a2a7-53e076acc062/task-scheduler-scheduler-status-is-being-running-always?forum=winservergen
you can add "exit" to last line of your script
cd "C:\Users\user\Desktop"
echo. 2>test.txt
exit
Running TASKKILL /F /IM cmd.exe will kill all cmd.exe processes whether it was the one that spawned this batch file or not. That's probably not desirable behavior. :-)
Judging by your last question, I'm guessing you're still running your task with cmd.exe /k, which will keep that window open indefinitely. For an unattended task, cmd.exe /c is a better choice. When the batch file finishes, the process should end.
Same here on Windows 7.
Putting all batch files in a directory in the user User specific path who runs the task
run programm = " cmd.exe " (without a path)
Your extras, mine where = " /c "C:\Users[username]\whatever\your_batchfile.bat" >> log.txt" "
" >> log.txt " so that i can see the output of the batch...
start in = " C:\Users[username]\whatever "
I also checked the "run with highest privilges" box
after that everything worked fine :)
Use following
exit /B
you may find more information in windows console area then type:exit/?
I know it's an old question, but I personally found that if I let a pause at the end of the bat file, it would keep the status as "Running".
I usually leave a pause at the end to help with debugging, but I found when I removed it, the task scheduler finally recognised it as having exited. It didn't help if I just refreshed it.
The solution I found was to add this line at the very end of the batch file:
TASKKILL /F /IM cmd.exe
Now after the batch file task runs and completes, it is no longer in the All Running Tasks list and the status goes back to 'Ready' instead of staying at 'Running'.
Warning:
That command will kill all running command processor instances so it may be potentially harmful!