I want to create a Windows BAT or VBS that tries to start a program silently. If the program does not exist, I would like it to terminate silently, without showing any alert window.
I am trying the following bat named startSilently.bat:
#echo off
start %1
When I type startSilently.bat chrome in CMD, Google Chrome opens as it should.
But when I type startSilently.bat nonexistent, then I get a popup message telling me:
Windows cannot find 'nonExistent'. Make sure you typed the name
correctly, and then try again.
I wish this message did not show up. Is there a way to do this?
Note: I cannot use call instead of start because I don't know where the program is installed.
It can be done in a .vbs this way:
On Error Resume Next
WScript.CreateObject("WSCript.shell").run WScript.Arguments.Unnamed(0)
You then call it like that:
cscript scriptname.vbs appname
If in your start silently desire you prefer that the application start minimized, you can add the intWindowStyle argument with value = 7 like that:
On Error Resume Next
WScript.CreateObject("WSCript.shell").run WScript.Arguments.Unnamed(0),7
... but that may not work with all applications. For example, notepad will start minimized but not chrome.
Related
When I use slmgr /skms <URL> | cmd command in PowerShell it shows me a pop up that I must press the ok button after that I run slmgr /ato | cmd and again shows me another pop up that I press the ok button.
I don't want to press the ok button manually, can anybody help me if there is a solution for it, please?
I just disabled the uac in windows, but it does not help me.
What you are looking for is cscript. By just executing a vbs script file, output gets sent to dialog boxes, which need your interaction.
Using cscript, the desired output gets printed to your current stdout:
cscript C:\Windows\System32\slmgr.vbs /ato
That doesn't have anything to do with UAC and you might consider re-activating it.
But why is that?
slmgr is not a command nor is it an executable in windows. It's a script file written in VBScript. VBScript is a kind-of scripting version of VB, So it's good for your peace of mind not to deal with it too much.
If you type in slmgr /skms, what windows does is looking for a file named slmgr in its search paths (%PATH%), finding C:\Windows\System32\slmgr.vbs and deciding that, as its a .vbs file, executing wscript.exe with the file path and your arguments as parameter is the right thing to do.
WScript is the default interpreter for vbs files and just interprets the file and executes its code. On the other hand, there is cscript for console scripts.
If the author of the .vbs file decides to write a message to the user of their script, they usually use a statement like
Wscript.Echo "Hello, World!"
And thats where your confusion starts:
Executing this script in cscript means that Hello, World! is written to the console. (That's what you want to do)
Executing the same script using wscript renders a message box with a OK button. You can easily reproduce it yourself by creating a vbs file with the above statement.
The difference between cscript and wscript is also discussed in this question:
Difference between wscript and cscript
In a batch file I can get the width of the console window using one of the examples here:
Windows console width in environment variable
#echo off
for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do set CONSOLE_WIDTH=%%W
echo Console is %CONSOLE_WIDTH% characters wide
Similarly, I would like to know how to get the width of the parent shell's console when I run a VBscript from a Command Prompt. If I try running the above batch file from VBscript using:
CreateObject("WScript.Shell").Run "cmd /k FindWidth.bat"
A new console opens, and the width given by FindWidth.bat is for the new console window, not the console of the parent shell.
Using VBscript I can find the process ID of the parent shell using the following method: In a vbscript, how can i get the process id of the cmd.exe in which the vb script is running. Is there a way to do something similar to find its console column width? Maybe another method can be used since the process ID is known?
EDIT UPDATES:
I thank everyone for the comments. I'll try to add some more information of what I'm trying to accomplish. I have a kind of work around already but I was hoping for a slightly better solution.
The VBscript is run from a Command Prompt directly. Unfortunately, the VBscript is most likely run from wscript.exe because that is the default on normal Windows installations. But I still want to output error messages and other messages to the console and not to a popup window.
If I could guarantee it was run with cscript, there would be no problems. Restarting the VBscript with cscript starts a new process so any messages from the newly run csript VBscript go to a new console and not the original console.
I have a solution which works but it is clumsy because it uses a batch file wrapper with the same name as the .vbs but with a .bat extension instead of .vbs extension. All the batch script does is run the VBscript using cscript. It is mentioned in this topic: In vbscript, how do I run a batch file or command, with the environment of the current cmd prompt window?
I was hoping to find a way to get rid of the batch file wrapper but now I don't think it is possible.
I was trying another workaround which allows WScript to be used. Since the process ID of the console window can be obtained, a message can be sent to the original console window by first guaranteeing it is activated with:
objShell.AppActivate(ProcessID)
Then the script can immediately send a message to the original console with:
objShell.SendKeys ":: " & WindowMessage & "{enter}"
The trick is using "::" to make the message a comment that doesn't do anything. This works okay. One small problem is that it makes the console window use the comment for the last command buffer so if the user presses the up arrow or F3 etc, the comment is shown like it was a command they typed themselves. That is annoying but since it is just a comment, no errors are produced and it isn't much of a problem.
The part that is annoying is that the message appears on the same line as a normal command and doesn't look like a proper cscript sent message. The reason I wanted the width of the console is to format the message by buffering it with the proper number of spaces so that it looks identical to a message that would have been sent from cscript. Then it would look like real stdout output except for the ":: " at the start of the message.
The script could just read the default setting for the command prompt but that will not format it correctly in a lot of cases.
If I could find a way to go to a new line with SendKeys and send the message before the PROMPT appears, that would do the same thing. Is there a character that could be sent which would start a new line before the PROMPT appears??
Is there a way of using VBscript to inject a text message into the stdout of a specific console window. Being that the process ID is known of the console that should get the stdout, is it possible for the wscript VBscript to run another batch script or another program silently which could use the Process ID to inject a message into the stdout of the original console window.
Ultimately, all I wanted was to have the VBscript file be run directly in a Command Prompt that can output messages to that same console. But to do that properly seems to require the user type "cscript scriptname.vbs arguments" instead of just "scriptname arguments" which is how it should be possible but apparently isn't! Using a batch file wrapper is another option that kind of tricks the user into running a different batch file instead of the VBscript file directly. I guess I would need to redo the script in a real computer language instead of a scripting language to make it work properly. I really don't understand why this is so difficult to accomplish with VBscript when it seems like it should be trivial.
It is a bit annoying that Windows sets VBscript to use WScript by default when WScript doesn't allow any console output at all. But CSCript can do both Windows popups and console output. Why even have WScript vs CScript distinction at all when it seems like everything can be done with CScript alone?
I've created a simple batch file that kicks off my *.msi installer within our company, creating a log file of the process, then displays the log file after the installer has completed.
installAndLog.bat:
msiexec.exe /i "\\FileServer2\setup.msi" /l*v "C:\setupLog.txt"
"C:\setupLog.txt"
It works, but there are two (2) glitches that annoy me:
The black console box shows in the background the whole time the installer is running and the log file is being displayed. Q1: How do I hide that?
and
The console box will not close until the log file is no longer being viewed (i.e. notepad.exe is closed). Q2: Can I call the text file in a new process and simply exit?
I was a DOS lover back in the day, but that was too many years ago.
I don't think you can hide the console window when running a batch file. However you can use vbscript instead which will by default not create a console window.
Take the below and put it in a file with a .vbs extension:
Dim wshShell
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run "msiexec.exe /i ""\\FileServer2\setup.msi"" /l*v ""C:\setupLog.txt""", 1, true
wshShell.Run "C:\setupLog.txt"
All the double double quotes are there because the entire command must be surrounded by "'s and doubling them escapes them. The the documentation for WshShell.Run for more info.
Q1 - AFAIK you can't really hide the console window.
Q2 - Use the start command. This will launch the specified program (notepad) outside of the shell. It will also prevent the shell from waiting until the application closes to continue processing the batch script.
You might be better off changing the batch script to launch the MSI installer using the start command and having the installer launch notepad to view the log file once installation is complete.
If you really want to get these batch windows away, you'll have to switch over to something else. One simple alternative could be one of the scripting languages supported by the windows scripting host.
Or you try HTA (HTML applications) see here and here.
Run the dos script as a different user by scheduled task or as a service.
I have a script that pings a list of computers and tells me if I can be reached. For each computer I would like it to display whether or not it was reached on the command prompt, not as a pop-up message. I did Wscript.Echo, but it does a pop-up for each computer so it's really annoying to have to click OK over a 100 times.
How can I make it display on the command prompt itself?
If you call it like this it will print to the console:
cscript myscript.vbs
on start up i have a bat file run routine things for me
however, the black console pops up and stays open until everything is finished....
anyway to hide it and run it in background ? so it shouldn't appear minimized or system tray.
You can use a VBS script to achieve this. Either write all your code as VBS, or call your batch file like this:
'launch.vbs
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "mybatch.bat", 0
WshShell = Null
Create a shortcut to the file. On the new shortcut: Right click -> Properties. Go to the Shortcut tab, and choose "Run: Minimized." (This is assuming you're on WinXP).
This link should help you as helped me. I used the second solution that uses a program named quiet.exe
To use, just call quiet.exe program params_if_has.
My use example: quiet.exe php script.php
You can't really do that but if you are using the scheduler to run the batch file you can select "don't interact with desktop" when creating the job.
I once had a little program which could hide windows based on their title. So my startup batch first set a unique title with title and then called the other program to hide the window with said title. Worked fine but involves a little programming.
If you don't want to go that way, then you should use the Task Scheduler as tr4656 noted.
Try renaming your file to .cmd instead of .bat.
Or, if you're executing a .exe try:
start "" "C:\Program Files\SomeProg\someprog.exe"
Note: When using "start" you have to be at a command prompt.