batch file error handling after calling C# program - c#

I have a batch file that calls C# program. This C# program makes call to SQL Server database.
Sometimes it is unable to connect to the database and the exception handler prints stack trace and exits c# program. I want to try to run this program maximum of 5 times.
If it succeeds (before 5 tries) then go to next step (CheckStatus) else Error out and quit.
When I run this, It is printing %ERRORLEVEL% as zero even when C# program has an error.
#ECHO OFF
SET Header=-----------------------------------------------------
SET Logfile=C:\LOG\log.txt
set %ERRORLEVEL% = 0
echo %header%
ECHO Running the batch file >> %Logfile%
if '%1' == '' goto usage
if '%2' == '' goto usage
if '%1' == '/?' goto usage
if '%1' == '-?' goto usage
if '%1' == '?' goto usage
if '%1' == '/help' goto usage
SET SQLServer=dbsql\production
SET SQLUser=user1
SET SQLPass=pwd1
SET SQLCommandMaster=osql -S%SQLServer% -n -U%SQLUser% -P%SQLPass% -b -i
GOTO %1%
:Start
Set count=0
:RunCSharpProgram
set /a count+=1
ECHO starting RunCSharpProgram count >> %Logfile%
timeout /t 10
SET RunningStep="RunCSharpProgram"
start "" "C:\CSharpProject\GetData\GetData\bin\Debug\GetData.exe"
ECHO %ERRORLEVEL% >> %Logfile%
IF %ERRORLEVEL% ==1 and count LEQ 5 (GOTO RunCSharpProgram)
IF %ERRORLEVEL% ==1 and count EQ 5 (GOTO error)
IF %ERRORLEVEL% ==0 (GOTO CheckStatus)
:CheckStatus
ECHO Check Status of tables >> %Logfile%
REM %SQLCOMMANDMASTER% /Q "EXEC TestDB.dbo.CheckStatus"
goto end
:usage
echo Usage: %0 'start step' 'end step'
goto end
:error
REM ---------------------------------------------------------------------
ECHO ERROR RUNNING BatchFileTest.BAT >> %Logfile%
:end
echo %header% >> %Logfile%
echo END >> %Logfile%
Not sure what is wrong with this batch file.
Thanks
MR

When you use start, it would start a new shell to run your program.
Official documentation
Starts a separate Command Prompt window to run a specified program or command.
Since it is a separate command prompt you will NOT get back the error codes. So, simple solution do not use the start
instead of
start "" "C:\CSharpProject\GetData\GetData\bin\Debug\GetData.exe"
you can just use
"C:\CSharpProject\GetData\GetData\bin\Debug\GetData.exe"

Related

Batch file that utilizes mingw32 will start manually in Explorer, but immediately closes when using Process.Start() C#

I'm using Visual Studio 2019 and C# Windows Forms.
I'm trying to execute a batch file that contains the following commands:
C:\\devkitPro\\msys2\\msys2_shell.cmd -mingw32 -c "cd /d/HelloWorld/Assets && make"
There is a Makefile located in the /d/HelloWorld/Assets directory, as well as a C++ source file (*.cpp) and I would like to execute/compile it from my C# app.
NOTE: The batch file is located in the same location as the Makefile.
When I double-click the batch file in File Explorer, it runs and compiles the C++ source code just fine. But, when I run it via Process.Start(), it simply opens then almost instantly closes.
e.x. Process.Start(#"D:\HelloWorld\Assets\batch.bat"); doesn't work. It opens mingw32, but then instantly (or sometimes almost instantly) closes.
I'm not sure what to do next, I'd appreciate anyone's help.
EDIT: This is a long .cmd script, as it is msys2, so here it is:
#echo off
setlocal EnableDelayedExpansion
set "WD=%__CD__%"
if NOT EXIST "%WD%msys-2.0.dll" set "WD=%~dp0usr\bin\"
set "LOGINSHELL=bash"
set /a msys2_shiftCounter=0
rem To activate windows native symlinks uncomment next line
rem set MSYS=winsymlinks:nativestrict
rem Set debugging program for errors
rem set MSYS=error_start:%WD%../../mingw64/bin/qtcreator.exe^|-debug^|^<process-id^>
rem To export full current PATH from environment into MSYS2 use '-use-full-path' parameter
rem or uncomment next line
rem set MSYS2_PATH_TYPE=inherit
:checkparams
rem Help option
if "x%~1" == "x-help" (
call :printhelp "%~nx0"
exit /b %ERRORLEVEL%
)
if "x%~1" == "x--help" (
call :printhelp "%~nx0"
exit /b %ERRORLEVEL%
)
if "x%~1" == "x-?" (
call :printhelp "%~nx0"
exit /b %ERRORLEVEL%
)
if "x%~1" == "x/?" (
call :printhelp "%~nx0"
exit /b %ERRORLEVEL%
)
rem Shell types
if "x%~1" == "x-msys" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MSYS& goto :checkparams
if "x%~1" == "x-msys2" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MSYS& goto :checkparams
if "x%~1" == "x-mingw32" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MINGW32& goto :checkparams
if "x%~1" == "x-mingw64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MINGW64& goto :checkparams
if "x%~1" == "x-ucrt64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=UCRT64& goto :checkparams
if "x%~1" == "x-clang64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANG64& goto :checkparams
if "x%~1" == "x-mingw" shift& set /a msys2_shiftCounter+=1& (if exist "%WD%..\..\mingw64" (set MSYSTEM=MINGW64) else (set MSYSTEM=MINGW32))& goto :checkparams
rem Console types
if "x%~1" == "x-mintty" shift& set /a msys2_shiftCounter+=1& set MSYSCON=mintty.exe& goto :checkparams
if "x%~1" == "x-conemu" shift& set /a msys2_shiftCounter+=1& set MSYSCON=conemu& goto :checkparams
if "x%~1" == "x-defterm" shift& set /a msys2_shiftCounter+=1& set MSYSCON=defterm& goto :checkparams
rem Other parameters
if "x%~1" == "x-full-path" shift& set /a msys2_shiftCounter+=1& set MSYS2_PATH_TYPE=inherit& goto :checkparams
if "x%~1" == "x-use-full-path" shift& set /a msys2_shiftCounter+=1& set MSYS2_PATH_TYPE=inherit& goto :checkparams
if "x%~1" == "x-here" shift& set /a msys2_shiftCounter+=1& set CHERE_INVOKING=enabled_from_arguments& goto :checkparams
if "x%~1" == "x-where" (
if "x%~2" == "x" (
echo Working directory is not specified for -where parameter. 1>&2
exit /b 2
)
cd /d "%~2" || (
echo Cannot set specified working diretory "%~2". 1>&2
exit /b 2
)
set CHERE_INVOKING=enabled_from_arguments
rem Ensure parentheses in argument do not interfere with FOR IN loop below.
set msys2_arg="%~2"
call :substituteparens msys2_arg
call :removequotes msys2_arg
rem Increment msys2_shiftCounter by number of words in argument (as cmd.exe saw it).
rem (Note that this form of FOR IN loop uses same delimiters as parameters.)
for %%a in (!msys2_arg!) do set /a msys2_shiftCounter+=1
)& shift& shift& set /a msys2_shiftCounter+=1& goto :checkparams
if "x%~1" == "x-no-start" shift& set /a msys2_shiftCounter+=1& set MSYS2_NOSTART=yes& goto :checkparams
if "x%~1" == "x-shell" (
if "x%~2" == "x" (
echo Shell not specified for -shell parameter. 1>&2
exit /b 2
)
set LOGINSHELL="%~2"
call :removequotes LOGINSHELL
set msys2_arg="%~2"
call :substituteparens msys2_arg
call :removequotes msys2_arg
for %%a in (!msys2_arg!) do set /a msys2_shiftCounter+=1
)& shift& shift& set /a msys2_shiftCounter+=1& goto :checkparams
rem Collect remaining command line arguments to be passed to shell
if %msys2_shiftCounter% equ 0 set SHELL_ARGS=%* & goto cleanvars
set msys2_full_cmd=%*
for /f "tokens=%msys2_shiftCounter%,* delims=,;= " %%i in ("!msys2_full_cmd!") do set SHELL_ARGS=%%j
:cleanvars
set msys2_arg=
set msys2_shiftCounter=
set msys2_full_cmd=
rem Setup proper title and icon
if "%MSYSTEM%" == "MINGW32" (
set "CONTITLE=MinGW x32"
set "CONICON=mingw32.ico"
) else if "%MSYSTEM%" == "MINGW64" (
set "CONTITLE=MinGW x64"
set "CONICON=mingw64.ico"
) else if "%MSYSTEM%" == "UCRT64" (
set "CONTITLE=MinGW UCRT x64"
set "CONICON=ucrt64.ico"
) else if "%MSYSTEM%" == "CLANG64" (
set "CONTITLE=MinGW Clang x64"
set "CONICON=clang64.ico"
) else (
set "CONTITLE=MSYS2 MSYS"
set "CONICON=msys2.ico"
)
if "x%MSYSCON%" == "xmintty.exe" goto startmintty
if "x%MSYSCON%" == "xconemu" goto startconemu
if "x%MSYSCON%" == "xdefterm" goto startsh
if NOT EXIST "%WD%mintty.exe" goto startsh
set MSYSCON=mintty.exe
:startmintty
if not defined MSYS2_NOSTART (
start "%CONTITLE%" "%WD%mintty" -i "/%CONICON%" -t "%CONTITLE%" "/usr/bin/%LOGINSHELL%" --login !SHELL_ARGS!
) else (
"%WD%mintty" -i "/%CONICON%" -t "%CONTITLE%" "/usr/bin/%LOGINSHELL%" --login !SHELL_ARGS!
)
exit /b %ERRORLEVEL%
:startconemu
call :conemudetect || (
echo ConEmu not found. Exiting. 1>&2
exit /b 1
)
if not defined MSYS2_NOSTART (
start "%CONTITLE%" "%ComEmuCommand%" /Here /Icon "%WD%..\..\%CONICON%" /cmd "%WD%\%LOGINSHELL%" --login !SHELL_ARGS!
) else (
"%ComEmuCommand%" /Here /Icon "%WD%..\..\%CONICON%" /cmd "%WD%\%LOGINSHELL%" --login !SHELL_ARGS!
)
exit /b %ERRORLEVEL%
:startsh
set MSYSCON=
if not defined MSYS2_NOSTART (
start "%CONTITLE%" "%WD%\%LOGINSHELL%" --login !SHELL_ARGS!
) else (
"%WD%\%LOGINSHELL%" --login !SHELL_ARGS!
)
exit /b %ERRORLEVEL%
:EOF
exit /b 0
:conemudetect
set ComEmuCommand=
if defined ConEmuDir (
if exist "%ConEmuDir%\ConEmu64.exe" (
set "ComEmuCommand=%ConEmuDir%\ConEmu64.exe"
set MSYSCON=conemu64.exe
) else if exist "%ConEmuDir%\ConEmu.exe" (
set "ComEmuCommand=%ConEmuDir%\ConEmu.exe"
set MSYSCON=conemu.exe
)
)
if not defined ComEmuCommand (
ConEmu64.exe /Exit 2>nul && (
set ComEmuCommand=ConEmu64.exe
set MSYSCON=conemu64.exe
) || (
ConEmu.exe /Exit 2>nul && (
set ComEmuCommand=ConEmu.exe
set MSYSCON=conemu.exe
)
)
)
if not defined ComEmuCommand (
FOR /F "tokens=*" %%A IN ('reg.exe QUERY "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\ConEmu64.exe" /ve 2^>nul ^| find "REG_SZ"') DO (
set "ComEmuCommand=%%A"
)
if defined ComEmuCommand (
call set "ComEmuCommand=%%ComEmuCommand:*REG_SZ =%%"
set MSYSCON=conemu64.exe
) else (
FOR /F "tokens=*" %%A IN ('reg.exe QUERY "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\ConEmu.exe" /ve 2^>nul ^| find "REG_SZ"') DO (
set "ComEmuCommand=%%A"
)
if defined ComEmuCommand (
call set "ComEmuCommand=%%ComEmuCommand:*REG_SZ =%%"
set MSYSCON=conemu.exe
)
)
)
if not defined ComEmuCommand exit /b 2
exit /b 0
:printhelp
echo Usage:
echo %~1 [options] [login shell parameters]
echo.
echo Options:
echo -mingw32 ^| -mingw64 ^| -ucrt64 ^| -clang64 ^| -msys[2] Set shell type
echo -defterm ^| -mintty ^| -conemu Set terminal type
echo -here Use current directory as working
echo directory
echo -where DIRECTORY Use specified DIRECTORY as working
echo directory
echo -[use-]full-path Use full current PATH variable
echo instead of trimming to minimal
echo -no-start Do not use "start" command and
echo return login shell resulting
echo errorcode as this batch file
echo resulting errorcode
echo -shell SHELL Set login shell
echo -help ^| --help ^| -? ^| /? Display this help and exit
echo.
echo Any parameter that cannot be treated as valid option and all
echo following parameters are passed as login shell command parameters.
echo.
exit /b 0
:removequotes
FOR /F "delims=" %%A IN ('echo %%%1%%') DO set %1=%%~A
GOTO :eof
:substituteparens
SETLOCAL
FOR /F "delims=" %%A IN ('echo %%%1%%') DO (
set value=%%A
set value=!value:^(=x!
set value=!value:^)=x!
)
ENDLOCAL & set %1=%value%
GOTO :eof
This approach will only work in Windows.
System.Diagnostics.Process.Start("explorer.exe", pathToBatFile);
This utilizes File Explorer, and runs the .bat file using File Explorer, and successfully compiles the C++ source code (main.cpp) using the Makefile.
The .bat file contains the following:
call C:\devkitPro\msys2\msys2_shell.cmd -mingw32 -c "cd /d/HelloWorld/Assets && make"
..That will successfully make the Makefile located in D:\HelloWorld\Assets.
NOTE: devkitPro needs to be installed for the .bat and the code to work correctly.

Can you output text when the commit passes in SVN?

We are using SVN and I would like to check the commit message for an string and give a warning that commits without this string will be bounced starting next month but currently allow the commit through.
stderr is only outputted when the commit fails, how do I allow the commit to succeed but still provide output to the user (I am writing the hook in C#)?
Per your response above, here is the windows batch solution.
In the post-commit hook
:: repos = full path to physical repository
:: rev = the revision number related to the transaction committed
:: reposname = the name of the repository
set repos=%1
set rev=%2
set reposname=%~nx1
set Unwanted_String=string value
:: Capture commit message
svnlook log %repos% -r %rev%>%reposname%_%rev%_commit_statement.txt
:: Verify commit message meets requirements
powershell -command "If (Get-Content '%reposname%_%rev%_commit_statement.txt' | Where-Object { $_ -match '%Unwanted_String%'}) {'Found'} else {'Not found'}">%reposname%_%rev%_Is_String_Present.txt
:: Determine if feedback is needed
set /p Commit_Search=<%reposname%_%rev%_Is_String_Present.txt
if "%Commit_Search%"=="Found" (
echo ----------------------------------------------------->&2
echo The string %Unwanted_String% is not allowed >&2
echo In the future, please do not include this as part of your commit statement >&2
echo. >&2
echo Your change has been committed>&2
echo ----------------------------------------------------->&2
del *%reposname%_%rev%*.txt
exit /b 1
)
The output back to the user will show the object was committed along with an error message
post-commit hook failed (exit code 1) with output:
The string xxxxxx is not allowed
In the future, please do not include this as part of your commit statement
Your change has been committed
Once the grace period is over and you want to reject commit statements that contain this string, move the above lines to your pre-commit hook with one change
:: Capture commit message (-t is transaction in progress)
svnlook log -t %rev% %repos%>%reposname%_%rev%_commit_Statement.txt
Moving this to the pre-commit hook will prevent the commit and inform the user as to why it was rejected.

ILmerge does not implement Newtonsoft.json

The second day I beat my head against the wall and can not figure it out.
How it is possible to implement this dll, any mistakes constantly jump out.
I tried many different options that are on the Internet. Nothing helped.
Help me figure out how to solve the problem.
How to implement Newtonsoft.Json in my project via ILMerge?
Thank you in advance.
Error:
leave command
""C:\Users\User\Desktop\FastFoodDemo\ILMerge\merge_all.bat"
"C:\Users\User\Desktop\FastFoodDemo\"
"C:\Users\User\Desktop\FastFoodDemo\FastFoodDemo\bin\Debug\RCC.exe"
Debug" with code 1. FastFoodDemo
Event final assembly:
"$(SolutionDir)\ILMerge\merge_all.bat" "$(SolutionDir)" "$(TargetPath)" $(ConfigurationName)
merge_all.bat
#ECHO OFF
rem # set .NET version and output folder name
set net="v4, C:\Windows\Microsoft.NET\Framework\v4.0.30319"
set output=Output
rem # process arguments
set ILMergeSolution=%1ILMerge\ILMerge.exe
rem # determine programm files of x86 for 32 and 64 Platform
IF EXIST "%PROGRAMFILES(x86)%" set prorgammFiles=%PROGRAMFILES(x86)%
IF NOT EXIST "%PROGRAMFILES(x86)%" set prorgammFiles=%PROGRAMFILES%
rem # if ILMerge.exe not in the $(SolutionDir)ILMerge\
rem # then try to use installed in prorgammFiles
IF EXIST %ILMergeSolution% set ILMerge="%ILMergeSolution%"
IF NOT EXIST %ILMergeSolution% set ILMerge=%prorgammFiles%\Microsoft\ILMerge\ILMerge.exe
set target_path=%2
set target_file=%~nx2
set target_dir=%~dp2
set ConfigurationName=%3
rem # set output path and result file path
set outdir=%target_dir%%output%
set result=%outdir%\%target_file%
rem # print info
#echo Start %ConfigurationName% Merging %target_file%.
#echo Target: %target_path%
#echo target_dir: %target_dir%
#echo Config: %ConfigurationName%
rem # recreate outdir
IF EXIST "%outdir%" rmdir /S /Q "%outdir%"
md "%outdir%"
rem # run merge cmd
#echo Merging: '"%ILMerge%" /wildcards /targetplatform:%net% /out:"%result%" %target_path% "%target_dir%*.dll"'
"%ILMerge%" /wildcards /targetplatform:%net% /out:"%result%" %target_path% "%target_dir%*.dll"
rem # if succeded
IF %ErrorLevel% EQU 0 (
rem # clear real output folder and put there result assembly
IF %ConfigurationName%==Release (
del %target_dir%*.*
del %target_dir%*.dll
del %target_dir%*.pdb
del %target_dir%*.xml
del %target_dir%*.*
copy %result% %target_dir%
rmdir /S /Q %outdir%
set result=%target_path%
#echo Result: %target_file% "-> %target_path%"
) ELSE (
#echo Result: %target_file% "-> %result%" )
set status=succeded
set errlvl=0
) ELSE (
set status=failed
set errlvl=1
)
#echo Merge %status%
exit %errlvl%

Mono-Service2 - Init.d script not working

I have created the init.d script below for my C# windows service to be executed on an Amazon Linux EC2 Instance. I hope Amazon linux is based on fedora linux.
I have below init.d script and I googled and found the script.
but if I start the service using the following command:
sudo service amaziersysd start
I am getting below error message:
cat: /tmp/amaziersysd.lock: No such file or directory
Pls note : I am newbie in setting up mono, and I am running mono 3.2.3 built from source.
#!/bin/sh
daemon_name=amaziersysd
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
exit 0
fi
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/mono/mono-service2
NAME=amaziersysd
DESC=amaziersysd
MONOSERVER=$(which mono-service2)
MONOSERVER_PID=$(cat /tmp/amaziersysd.lock)
case "$1" in
start)
stat_busy "Starting amaziersysd"
if [ -z "${MONOSERVER_PID}" ]; then
${MONOSERVER} -l:/tmp/amaziersysd.lock /etc/amazierlb/sysdaemon/Amazier.CollectSysStat.exe
stat_done
else
echo "amaziersysd is already running!"
stat_fail
fi
;;
stop)
stat_busy "Stopping amaziersysd"
if [ -n "${MONOSERVER_PID}" ]; then
kill ${MONOSERVER_PID}
rm /tmp/amaziersysd.lock
stat_done
else
echo "amaziersysd is not running"
stat_fail
fi
;;
restart)
$0 stop
sleep 1
$0 start
stat_done
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
exit 0

Remote Process Execution using Wmi win32_Process - Getting Stdout of Process

Hi i am able to execute a remote process using Wmi and was able to get return Value and Process Id of the Process. Is there any way to get the Output of the Process which was started by Wmi. Eg. If i start an exe which prints something in console will i be able to get those values using this Api. Any help is appreciated.
You must redirect the output to a file, then read the file across the network.
Use the CMD.EXE /S /C option to do this.
Example command line to run Program.exe:
CMD.EXE /S /C " "c:\path\to\program.exe" "argument1" "argument2" > "c:\path\to\stdout.txt" 2> "c:\path\to\stderr.txt" "
Then connect to server like this \\servername\c$\path\to\stdout.txt to read the stdout results.
Note: Pay careful attention to the extra quotes around the command to run. These are necessary to ensure the command line is interpreted correctly.
You can use psexec to execute the program.exe and get the stdout by pipe
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while p.poll() is None:
line = p.stdout.readline()
line = line.strip().decode('gbk')
if line:
print('Subprogram output: [{}]'.format(line))
if p.returncode == 0:
print('Subprogram success')
return True
else:
print('Subprogram failed')
return False

Categories