ERRORLEVEL cannot report regsvr32's process exit code, why? - cmd

On Windows 7 SP1, from CMD window, run command regsvr32 none.dll, regsvr32 will fail with exit code 3. This is the expected behavior of regsvr32, as stated in Raymond Chen's blog post.
Procmon verifies this as well.
However, when checking regsvr32's exit code with echo %ERRORLEVEL%, I got zero. WHY?

Thanks to Marks comment. I was just tripped by CMD's sneaky behavior.
To know the exit code of a GUI process like regsvr32, the CMD command line has to be:
start /wait regsvr32.exe none.dll
What is special about regsvr32 is: If we run regsvr /s xxx.dll , /s makes regsvr totally silent, looking very much like a CUI program. So users are more easily get trapped.
But if we execute regsvr32 none.dll inside a .bat/.cmd batch script, start /wait is not required. Such discrepancy (on command prompt vs inside batch script) often causes trouble for the unwary. Sigh.

Related

How to use a .bat file to run other .bat(s) and have each one in a seperate cmd prompt in different directory locations

start cmd
cd /d C:\U\O\D\L\D\M
call runbot.bat
cd /d C:\U\O\D\L\F
call RunBossBot.bat
My issue is switching between cmd windows, it attempts to put everything in one window.
Grateful for any help,
Thanks
start "" "c:\somewhere\runbot.bat"
start "" "c:\somewhere\RunBossBot.bat"
Starting a Program
See start /? and call /? for help on all three ways.
Specify a program name
c:\windows\notepad.exe
In a batch file the batch will wait for the program to exit. When
typed the command prompt does not wait for graphical
programs to exit.
If the program is a batch file control is transferred and the rest of the calling batch file is not executed.
Use Start command
start "" c:\windows\notepad.exe
Start starts a program and does not wait. Console programs start in a new window. Using the /b switch forces console programs into the same window, which negates the main purpose of Start.
Start uses the Windows graphical shell - same as typing in WinKey + R (Run dialog). Try
start shell:cache
Use Call command
Call is used to start batch files and wait for them to exit and continue the current batch file.

How to run VS2010 command prompt from CruiseControl.Net

I have a .bat file that has the following commands:
c:
cd %1
"c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64 & for /f "delims==" %%F in ('dir /b *.pdb') do vsinstr /Coverage "%%~nF.dll"
I am executing the bat file from a cruise control project like this:
<exec>
<executable>cmd.exe</executable>
<buildArgs>"c:\Development\Batch Scripts\CodeCoverageSetup.bat" $(CodeCoverageSetupWorkingDirectory)</buildArgs>
</exec>
When the CC.Net project runs, the task is executed but it does nothing, and it runs indefinitely.
However, when I execute the batch script directly from cmd it executes perfectly.
Any ideas on how to get this to work?
PS: Any suggestions on how I can make CC.Net run the cmd window so that I can see what commands are being executed? Because the CC.Net shell does not give any useful debug info.
You are missing the /c for the cmd.exe to execute another process and exit at end.
Fixed exec block:
<exec>
<executable>cmd.exe</executable>
<buildArgs>/c "c:\Development\Batch Scripts\CodeCoverageSetup.bat" $(CodeCoverageSetupWorkingDirectory)</buildArgs>
</exec>
OR you can simply remove cmd.exe reference.
<exec>
<executable>c:\Development\Batch Scripts\CodeCoverageSetup.bat</executable>
<buildArgs>$(CodeCoverageSetupWorkingDirectory)</buildArgs>
</exec>
I can answer one part.
//PS: Any suggestions on how I can make CC.Net run the cmd window so that I can see what commands are being executed? Because the CC.Net shell does not give any useful debug info. //
Shut down the CC.NET (Service) (as in Control Panel-Services).
Run ccnet.exe from the command line. (It's values are pulled from ccnet.exe.config).
This will show everything that is happening in a command-window.
......
You can try the .bat file, but I usually end up recoding whatever happens in (what would be your "CodeCoverageSetup.bat") with a Task.
But I understand if you have a alot in CodeCoverageSetup.bat.
Try the command-prompt method and maybe it'll give you a hint about what is happening.

cmd.exe will not terminate under certain conditions when launched with the CreateProcess function

I am executing batch commands via a C program with the CreateProcess function. I check to see if the process has terminated with the GetExitCodeProcess function, by checking to see if the process exit code equals anything except STILL_ACTIVE. This works fine with commands like "cmd /c echo Hello World", but for commands like "cmd /c dir c:\windows" or "cmd /c dir c:\windows & exit", cmd.exe will never terminate. Either command when launched thru the command prompt will terminate as expected. Does anyone know why it never terminates when launched via CreateProcess? Thanks a lot.
Apparently I have to start to read the stdout/stderr pipe in the loop which checks to see if the process is still running, as well as read it after the process has terminated. Rather than just read it after the process has terminated. Many thanks to Wimmel for posting the answer.

Pausing a batch file when double-clicked but not when run from a console window?

Is there a way for a batch file (in this case, running on Windows XP) to determine whether it was launched from a command line (i.e. inside a console window) or launched via the shell (e.g. by double-clicking)?
I have a script which I'd like to have pause at certain points when run via the shell, but not when run at a command line. I've seen a similar question on SO, but am unable to use the same solution for two reasons: first, whether or not it pauses needs to be dependent on multiple factors, only one of which is whether it was double-clicked. Second, I'll be distributing this script to others on my team and I can't realistically ask all of them to make registry changes which will affect all scripts.
Is this possible?
Found one :-) – After desperately thinking of what cmd might do when run interactively but not when launching a batch file directly ... I finally found one.
The pseudo-variable %cmdcmdline% contains the command line that was used to launch cmd. In case cmd was started normally this contains something akin to the following:
"C:\Windows\System32\cmd.exe"
However, when launching a batch file it looks like this:
cmd /c ""C:\Users\Me\test.cmd" "
Small demo:
#echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
This way of checking might not be the most robust, though, but /c should only be present as an argument if a batch file was launched directly.
Tested here on Windows 7 x64. It may or may not work, break, do something weird, eat children (might be a good thing) or bite you in the nose.
A consolidated answer, derived from much of the information found on this page (and some other stack overflow pages with similar questions). This one does not rely on detecting /c, but actually checks for the name of the script in the command line. As a result this solution will not pause if you double-clicked on another batch and then called this one; you had to double-click on this particular batch file.
:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
The variable "testl" gets the full line of the cmd processor call, stripping out all of the pesky double quotes.
The variable "testr" takes "testl" and further strips outs the name of the current batch file name if present (which it will be if the batch file was invoked with a double-click).
The if statement sees if "testl" and "testr" are different. If yes, batch was double-clicked, so pause; if no, batch was typed in on command line (or called from another batch file), go on.
Edit: The same can be done in a single line:
echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
In plain English, this
pipes the value of %cmdcmdline% to findstr, which then searches for the current script name
%0 contains the current script name, of course only if shift has not been called beforehand
%~nx0 extracts file name and extension from %0
>NUL 2>&1 mutes findstr by redirecting any output to NUL
findstr sets a non-zero errorlevel if it can't find the substring in question
&& only executes if the preceding command returned without error
as a consequence, standalone will not be defined if the script was started from the command line
Later in the script we can do:
if defined standalone pause
One approach might be to create an autoexec.nt file in the root of c:\ that looks something like:
#set nested=%nested%Z
In your batch file, check if %nested% is "Z" - if it is "Z" then you've been double-clicked, so pause. If it's not "Z" - its going to be "ZZ" or "ZZZ" etc as CMD inherits the environment block of the parent process.
-Oisin
A little more information...
I start with a batch-file (test.cmd) that contains:
#echo %cmdcmdline%
If I double-click the "test.cmd" batch-file from within Windows Explorer, the display of echo %cmdcmdline% is:
cmd /c ""D:\Path\test.cmd" "
When executing the "test.cmd" batch-file from within a Command Prompt window, the display of
echo %cmdcmdline% depends on how the command window was started...
If I start "cmd.exe" by clicking the "Start-Orb" and "Command Prompt" or if I click "Start-Orb" and execute "cmd.exe" from the search/run box. Then I execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
"C:\Windows\system32\cmd.exe"
Also, for me, if I click "Command Prompt" from the desktop shortcut, then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is also:
"C:\Windows\system32\cmd.exe"
But, if I "Right-Click" inside a Windows Explorer window and select "Open Command Prompt Here", then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
"C:\Windows\System32\cmd.exe" /k ver
So, just be careful, if you start "cmd.exe" from a shortcut that contains a "/c" in the "Target" field (unlikely), then the test in the previous example will fail to test this case properly.

interactive window to execute dos commands in visual studio

I know using External Tools options i can run a batch script or a cmd prompt. But here is what i need to do
I want to be able to call a dos prompt inside visual studio, which must be interactive. That way i won't be outside visual studio and can run all my dos commands in it. Is it possible? Or can i extend the command window and capture the commands which are typed and process them using my custom code?
Thanks
There's the Tools.Shell command which may work for you. You use the /c switch to specify that the output for the executable is displayed in the Command window. Then you call cmd.exe with /C switch which instructs it to close after finishing the command. For example if you type:
Tools.Shell /c cmd.exe /C dir C:
This will print the output to the Command window. Unfortunately, unlike the output, the input doesn't work. So if you type:
Tools.Shell /c cmd.exe /C pause
The prompt will not wait for your input (pressing a key).
If that's OK for you, you can even define an alias for most of this. For example you define alias sh for Tools.Shell /c cmd.exe /C:
alias sh Tools.Shell /c cmd.exe /C
Then you simply use it as follows:
sh dir c:
If you install NuGet, then it adds Package Manager Console to Visual Studio which is essentially a Powershell command prompt. There should be ways of doing most DOS stuff via Powershell and heaps more functionality as well.
Not exactly what you are asking for, but I think you could manage to achieve your goal with StudioShell:
http://studioshell.codeplex.com/
Have to admit that I did not use it so far but it looks very interesting.

Resources