Visual Studio Pre-Build Event: Batch File Exit Code is -1 - visual-studio-2010

In order to work around the issue IIS Express Blocks VS 2010SP1 Builds I have created a simple batch file
taskkill /IM iisexpress.exe
exit 0
and set that batch file as a pre-build event.
If IIS Express is actually running, it works great. However, if IIS Express is not running the build fails with the following output:
The process "iisexpress.exe" not found.
The command "E:\Software\Util\KillIisExpress.bat" exited with code -1.
If instead of the batch file I use the taskkill command as the pre-build event, the error changes to
The command "taskkill /IM iisexpress.exe" exited with code 128.
How can I modify the batch file so that, no matter what exit code taskkill returns, the batch file returns with an exit code of 0 so that the VS build succeeds?

You can use
taskkill /FI "IMAGENAME eq iisexpress.exe"
which will output an info message if iisexpress.exe isn't running, but will return 0. You don't need the batch file with this, just add the command as the Pre-Build Event Command Line.

Related

Can I call %COMSPEC% without terminating all Windows batch execution?

Came across this oddity of batch behaviour as part of the build process in our systems that I'm trying to automate in Jenkins pipelines.
To skip to the meat of the problem and why I'm encountering it, the batch file I'm calling is a build generated batch file that must be called prior to another executable within the same command window to set up paths and alike for our executable to build our system. When building as a user this is fine, you just open the cmd console, run the batch, then run the executable. However in Jenkins I have to pass all commands effectively as one batch file to make it call within the same window, unless I want to mess around with configuring all those paths by hand using withEnv or something.
Something along the lines of this in my Jenkins groovy script:
// Option 1 - && operator
bat "env_configuration.bat && env_dependent_exec.exe"
// Option 2 - multi line version
bat """env_configuration.bat
env_dependent_exec.exe
"""
// Option 3 - same using calls, yadda yadda
bat """call env_configuration.bat
call env_dependent_exec.exe
"""
// Option 4 - Place these calls in batch file and call that instead
bat "run_it_all.bat"
As part of the batch file however, for whatever reason, it has this command within it.
%COMSPEC%
exit /b 0
This will call "C:\WINDOWS\system32\cmd.exe" and output the Mircrosoft version and related blurb.e.g:
Microsoft Windows [Version 10.0.19045.2486]
(c) Microsoft Corporation. All rights reserved.
The catch is, calling this executable will immediately end all batch execution. The line "exit /b 0" isn't actually hit, something whoever created this process I assume never realised. After this batch file process completes, all subsequent commands/calls, (Option 1 above is the easiest to repro) are never hit as all batch processing just stops. This is visible directly in cmd itself, you don't need Jenkins to reproduce.
I will probably wind up just find and replacing this line to comment it out or something... but I refuse to believe I can't find some way of stopping %COMSPEC% from ending all execution of whatever batch file calls it. If I were to guess, I would guess that cmd.exe calls EXIT as it finishes and kills all....
For the sake of interest I have tried modifying the batch file in numerous ways to try and see if I can call %COMSPEC% and still get the rest of the batch script to run afterwards.
:: This fails the same way
call %COMSPEC%
exit /b 0
:: This succeeds to run, but spawns another cmd window that doens't print in the original calling batch file output, so doesn't achieve the original goal
start %COMSPEC%
exit /b 0
:: call %COMSPEC% via subroutine also immediately terminates, we never see "echo 2"
call :comspec_call
exit /b 0
:comspec_call
#echo %COMSPEC% echo 1
%COMSPEC%
#echo %COMSPEC% echo 2
I would guess cmd.exe calls the EXIT command flat on termination, hence the process death, but I've yet to find a means to prevent it doing so...
I've checked %COMSPEC% for flags that might just printout and terminate nicely, but any flags I've found that do provide this information, also terminate with EXIT (I think)
Does anyone has any idea how to call this line and continue execution as I assume the original dev intended?
Cheers in advance!
Batch processing doesn’t just stop — you have started another command interpreter, and the one that launched it is waiting for the new instance to terminate. As it doesn’t quit, everything appears to halt and you wind up killing both to get things back to normal.
Create a new batch script that does everything:
:: controller.bat
#echo off
call env_configuration.bat
call some_other.bat
env_dependent_exec.exe
...
Use of the call command causes the command shell to invoke a script using the current interpreter.
Now your Jenkins groovy script should be:
bat controller.bat
(Disclaimer: I don’t know Jenkins, so...)
Thanks to #Duthomhas and #Magoo
The problem here is that a call to %COMSPEC% launches a new command line process that must terminate before the rest of the script can continue. I didn't understand that cmd.exe was spawning a new script that the call script was waiting to terminate.
With a simplified recap:
:: env_configuration.bat
#echo env_configuration before COMSPEC
#%COMSPEC%
#echo env_configuration after COMSPEC
:: controller.bat
#echo controller before env_configuration.bat
#call env_configuration.bat
#echo controller after env_configuration.bat
controller.bat && #echo back in shell
When you run controller.bat the process will output the Microsoft blurb, but halt.
If you enter "exit" at this point it will kick out of the terminal launched with %COMSPEC% and then all following script steps continue.
It appears the original dev needed the user to be in a new subprocess to continue. The final solution to doing as was intended here is:
:: env_configuration.bat
#echo env_configuration before COMSPEC
#call %COMSPEC% /C <whatever_command_or_exec_next>
#echo env_configuration after COMSPEC
:: controller.bat
#echo controller before env_configuration.bat
#call env_configuration.bat
#echo controller after env_configuration.bat
controller.bat && #echo back in shell
Cheers!

How to run a .bat file continuously using task scheduler?

I have a simple batch script which is coping file from a folder and then move those files to a different folder. i set a up a task scheduler which working fine. but if another task run the cmd before previous task end, it will mixed up with the copy/move file job. is there anyway we can set the task scheduler that next task will run "only if previous task end"?
here is the screenshot i currently set
https://i.imgur.com/DTcKj9t.png
As mentioned in the comments by Ikegami, You could use a lock file to test if the batch file is running and let the same process delete the lock file when the script is done. You have to be sure though that the script cannot exit unexpectedly.
Another way is to add the following to the top of your batch-file
#echo off
tasklist /FI "WINDOWTITLE eq my_job_run" | findstr /i "cmd.exe"
if not errorlevel 1 exit
title my_job_run
This will check if a process by the name of cmd.exe exists with the window title of my_job_run if it does, exit and if it does not exist, continue and create the title, where the next run will detect it and not run the script again.

Batch to check if process exists

I'd like a batch that will check if the process firefox.exe exists (after it has been started by the start command).
If the process exists, it will go to the label :fullscreen,
else the batch will go the the label :timeout. Then, it will check again if the process firefox.exe exists and if not, it will go again to the label :fullscreen until the process exists.
Here is my batch:
#echo off
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
:timeout
timeout /t 5
:fullscreen
nircmd sendkeypress F11
exit
How can I do this check ?
You can also use QUERY PROCESS:
#Echo Off
If Not Exist "%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe" Exit/B
Start "" "%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe"
:Loop
Timeout 5 /NoBreak>Nul
QProcess firefox.exe>Nul 2>&1||GoTo :Loop
NirCmd SendKeyPress F11
I suggest for this task the batch file:
#echo off
start "" /max firefox.exe
if errorlevel 1 goto :EOF
set LoopCount=0
:WaitLoop
%SystemRoot%\System32\timeout.exe /T 5
%SystemRoot%\System32\tasklist.exe /FI "IMAGENAME eq firefox.exe" 2>nul | %SystemRoot%\System32\find.exe /I "firefox.exe" >nul
if not errorlevel 1 nircmd.exe sendkeypress F11 & goto :EOF
set /A LoopCount+=1
if not %LoopCount% == 6 goto WaitLoop
Let me explain the few command lines used here.
1. Starting Firefox
The command START being an internal command of cmd.exe interprets the first double quoted string as optional title for the console window. Therefore the command line
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
results just in opening a new console window with the window title:
C:\Program Files (x86)\Mozilla Firefox\firefox.exe
For that reason "" is specified as first START argument to define an empty title. Firefox is a GUI application. So no console window is opened which means an empty window title is really enough.
The parameter /max would not be really necessary, but the goal is to get Firefox into full screen mode after starting. So why not starting it already maximized?
32-bit version of Firefox is by default installed in directory %ProgramFiles% on 32-bit Windows and in %ProgramFiles(x86)% on 64-bit Windows. But it is possible during the installation to install Firefox into any other folder. But Firefox installer is well coded and registers firefox.exe in Windows registry under key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
This is recommended by Microsoft as written in MSDN article Application Registration.
The command START searches also in Windows registry under this key for an executable specified as argument without path as explained in answer on Where is “START” searching for executables?
This is the reason for using just firefox.exe on START command line because that starts an installed Firefox independent on installation location.
START displays an appropriate message box if firefox.exe could not be started and exits in this case with a return code greater 0 (9059 in my test on one computer).
The help output on running if /? in a command prompt window explains how to evaluate the exit code of a previous command or application without usage of immediate or delayed environment variable expansion and therefore working anywhere in a batch file from MS-DOS (really!) to currently latest Windows 10.
The command line if errorlevel 1 goto :EOF means IF start failed to start firefox.exe indicated by an exit code greater or equal 1 THEN exit execution of this batch file. For details on exiting batch file execution see answer on Where does GOTO :EOF return to?
2. Checking for running Firefox
The command TASKLIST being an external command, i.e. a console application in system directory of Windows, outputs a list of running processes. This list can be already filtered by TASKLIST itself for a specific process as done in batch file with /FI "IMAGENAME eq firefox.exe".
But TASKLIST is designed for just printing a list of processes. It is not designed for checking if a specific process is running and returning the result to the calling process via exit code. TASKLIST always exits with 0.
But an error message is output to handle STDERR on using a filter and no process can be found in process list matching this filter. For that reason 2>nul is used to suppress this error message by redirecting it to device NUL. Read the Microsoft article about Using Command Redirection Operators for more information about redirection.
A simple method to get a simple false/true respectively 0/1 result on checking for running Firefox is filtering output of TASKLIST with external command FIND which exits with 0 if the string to find was indeed found or with 1 if the searched string could not be found in the text read in this case from STDIN. The output of FIND is of no interest and therefore suppressed with redirection to device NUL using >nul.
Instead of using TASKLIST and FIND it is also possible to use QPROCESS:
%SystemRoot%\System32\qprocess.exe firefox.exe >nul 2>&1
QPROCESS exits with exit code 1 if firefox.exe could not be found in list of running processes. Otherwise the exit code is 0 on firefox.exe is running.
3. Evaluating Firefox process checking result
if not errorlevel 1 nircmd.exe sendkeypress F11 & goto :EOF
The IF command checks if exit code of FIND is NOT greater or equal 1 which means if exit code is lower than 1. Command FIND exits never with a negative value. So if this condition is true then it is time to execute nircmd.exe to send key press F11 to application in foreground hopefully being Firefox (not guaranteed by this code) and exit batch file processing.
Otherwise the batch file should wait once again 5 seconds and then do the check again. This can very easily result in an endless running batch file in case of started Firefox is immediately closed by the user before the 5 seconds wait timed out. For that reason it is counted how often the wait loop is already executed. After 6 loop runs, or 30 seconds, it is really time to no longer wait for Firefox and exit the batch file.
4. Getting more information about used commands
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
find /?
if /?
qprocess /?
set /?
start /?
tasklist /?
timeout /?
And Single line with multiple commands using Windows batch file should be also read explaining operator & in addition to all other web pages referenced already above.
You can show a list of opened programs like this:
tasklist
To check if firefox exists:
EDIT: Code edited to show a fully working example
#echo off
start "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
goto :checkloop
:checkloop
tasklist|find "firefox.exe" > NUL
if %ERRORLEVEL% == 0 (
call :fullscreen
exit
) else (
call :timeout
goto :checkloop
)
:fullscreen
nircmd sendkeypress F11
goto :EOF
:timeout
timeout /t 5
goto :EOF

bat file kill itself?

We currently have a scheduled task on a server, it runs a bat file which copies files from one machine to another. The file looks like:
#echo off
net use t: \\xxxxx\copy password /user:xxx\xyz /persistent:yes
move t:\*.txt C:\testfiles
net use t: /delete
taskkill /f /fi "USERNAME eq xyz" /im conhost.exe
exit
When the task runs I noticed in task manager cmd.exe and conhost.ext are started, I wanted to stop them once the task is done. Killing the conhost.ext manually seems to kill them both. The above bat file runs fine but the conhost.exe is not killed, I wasn't sure if it can kill itself? As running that line in another bat file works. As currently once the task is done those two are still showing up in task manager.
You can try to get the cmd.exe own process so you'll kill only the current instance of cmd.exe . You can use for example getCmdPID.bat:
#echo off
call getCmdPid.bat
taskkill /pid %errorlevel%
pause
conhost.exe is executed automatically for each console application and exits automatically when the application exits, you don't have to kill it explicitly. So just kill cmd.exe.

batch file restart or close running programs with time with no warning message

i'm working with batch file right now, I am trying to run a batch file that will restart or close a program with a given time with no warning message(for restart). is this possible? i know how to restart using a batch file but i can't find a way to hide or not show the warning message. tnx
Taskkill /?
taskkill /f /im notepad.exe

Resources