VS2019 Pre and Post build events always fails with code 1 - visual-studio

I have a solution with just echo Hello post-build event and it always fails with the message The command "echo Hello!" exited with code 1.
Has someone an idea what could go wrong?
More info:
we have a team with about 15 developers. It always fails just for 3 of them
we have all Windows 10 and VS2019
we have tried different scripts and ended up with the echo Hello
we have tried with the prod solution and with an empty one as well
Full error message:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\
Microsoft.Common.CurrentVersion.targets(1328,5):
error MSB3073: The command "echo Hello!" exited with code 1.
Edit
Just have compared the Microsoft.Common.targets file from a developer with working events to one with non-working events. They have the same content.

I don't have Visual Studio in front of me to test this, but the problem feels like ERRORLEVEL may sometimes (randomly?) be non-zero on entry to the post-build script.
The problem is that ECHO does not affect ERRORLEVEL:
dir FileThatDoesNotExist Gives "File not found".
echo %ERRORLEVEL% Prints "1" ... an error.
echo Hello Prints "Hello".
echo %ERRORLEVEL% Still prints "1".
Therefore, if error-level happens to be non-zero, it will not be reset by the ECHO command. (Neither, as far as I can see, does REM affect it). There may be other ways of doing so, but DIR . > nul seems to work for me in resetting ERRORLEVEL to zero (it should always be possible to run DIR on the current directory!). The redirect should stop the output appearing in the build-log.
Obviously, if there was an earlier command in the post-build script that had failed, you probably don't want to ignore it. However, the pattern you're seeing (some users fail, some work) suggests that for some reason, Visual Studio is sometimes launching the post-build script with a non-zero error-level: with an empty script, or only ECHO commands, this will end up as the "result" of the post-build stage and the problem you're seeing.
Adding DIR . > nul to the TOP of the script should ensure that the exit-code is reset (and will allow real failures later in the script to be detected).

So the problem was the username. We had some freelancers in our company and they got a username starting with some special character. I can't remember which one, but I guess underscore. So when the admin sorts users by their user name they are on the top.
Changing the username has solved the problem in all our cases -_-

Related

Escape # Sign Inside ECHO Command In Batch Script (Called Within VS Post-Build Event)

I simply want to display the # sign inside text that is output by an ECHO command in a CMD batch script that's invoked by a Visual Studio post-build event. How can I do that?
My one-line post-build event invokes my batch script like this:
if $(ConfigurationName) == Release call "$(ProjectDir)\..\MYBATCHSCRIPT.bat"
The file MYBATCHSCRIPT.bat simply states:
#ECHO OFF
ECHO Please create a separate batch file called C:\Temp\OTHERBATCH.bat and place this code inside it:
ECHO #ECHO OFF
ECHO ECHO Hi there!
call C:\Temp\OTHERBATCH.bat
I know there are escape characters (such as ^) that I can use to prefix special characters, but none seem to work for me so far! Help! This is my offending line in the script:
ECHO #ECHO OFF
The intended output for that line is:
#ECHO OFF
All I'm doing is I am providing a hint to the developer to write a separate, prerequisite, non-version-controlled two-line OTHERBATCH.bat batch file. He must write it for my build to work correctly. I am giving him an actual code sample in the build output display.
My code does output the intended result if I run it on a regular command line! It just fails with, "The syntax of the command is incorrect" when I call the batch script in a post-build event! All I just want to do is write "#ECHO OFF" on the screen for my post-build output!
To achieve my desired result (outputting "#ECHO OFF" to the Visual Studio output window, I've had to switch gears due to an unforeseen constraint in how MSBuild processes batch script *.bat files.
I've since learned that the command interpreter used during a Visual Studio post-build event must not be as full-featured as the one behind the CMD prompt that I can launch from Windows--though both run *.bat files. In my limited observation thus far, it will behave differently as follows:
Using apostrophes instead of REM throws an error
Any lines such as these throw an error:
ECHO ECHO OFF
#ECHO #ECHO OFF
The PAUSE command won't wait for the user to hit a key
My solution for the above question was to create a separate text file with the information that I wanted to display on the output window and then use the TYPE command to display it from within my batch script, like so:
TYPE INFO.TXT
Inside INFO.TXT I could place any text that I want to display, including the # sign and text like "#ECHO OFF", without issue.

Batch Script at Startup not Completing

I have a batch script to pull down the latest revision files from an SVN that runs at Windows startup (configured with local group policy editor).
Here is the code for the script:
#echo off
if "%1"=="" (
set LIBPATH=C:\ALTIUM_WORK\00001_MCHP-CDB\parts\Library
) else (
set LIBPATH=%1
)
svn cleanup %LIBPATH%
set DATETIME=%DATE:~4,2%/%DATE:~7,2%/%DATE:~10,4% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
echo %DATETIME%>mcl_update.log
svn up %LIBPATH%>>mcl_update.log
if ERRORLEVEL 1 goto ERRHANDLER
Exit
:ERRHANDLER
<Insert error message here>
When I run this script by double-clicking the .bat, I get the following output in mcl_update.log:
02/14/2017 16:13:50
Updating 'C:\ALTIUM_WORK\00001_MCHP-CDB\parts\Library':
At revision 5800.
This is what I expect, but when the script runs at startup, the last line is left out. It populates mcl_update.log with this:
02/14/2017 16:16:07
Updating 'C:\ALTIUM_WORK\00001_MCHP-CDB\parts\Library':
The second line is part of the output from svn, so it seems like the command starts, but just never finishes. I'm at a loss for why this is happening. Does anyone have any ideas?
Thanks!
-Sean
A newly-discovered bit of info: After startup, if I try to delete the log file that is generated, Windows throws an error stating that "The action can't be completed because the file is open in cmd.exe".
Is it possible that this could be a domain issue? The connection to my company's network isn't up yet, so the svn command just hangs?
I suspect that the path is not what you are expecting during start-up. Perhaps you should explicitly specify the path for svn because the only report you are apparently logging is a plain echo, not any reponse from svn.
So after following #Magoo's suggestion of piping stderr out to the file, the issue became clear. It turns out it has to do with my server's user authentication. Since the script was running at startup (i.e. before I logged in), the svn command wouldn't work, as user authentication was impossible.
I changed the group policy to start the script at logon, rather than startup, and everything works now.

Why do all Pre-build or Post-build events in Visual Studio fail with exit code 1?

My goal is copying an .exe file from a bin folder of solution A to another solutions B resource folder on the post build event of solution A.
I created the necessary xcopy command and tried it out in powershell: It works perfectly.
Whenever I add any command to the actions in VS build fails with: "#command# exited with code 1", where #command# is, for example, the xcopy command.
I tried running VS as admin and currently I tried just running a .bat file that contains "#echo off #exit 0". That too leads to "#command# exited with code 1".
Have some example of what I tried out as VS post/pre-build command:
call "projdir\test.bat"
call projdir\test.bat
"projdir\test.bat"
projdir\test.bat... I tried projdir as "$(ProjectPath)" and manual path.
I put output to verbose and found the following:The command "C:\Users\Traubenfuchs\AppData\Local\Temp" is written incorrectly or couldn't be found. (That folder actually exists but I don't know what it wants to do it.)The same thing happens when I put an xcopy command in pre/post build.
Anyone knows what I am doing wrong?
Recently I met similar problem.
About your "hello world" post-build event :
try to call powershell directly
powershell -command "write-output 'hello world'; exit 0"
=================
My pre-build event looks like :
powershell -file scriptPath.ps1
My scriptPath.ps1 looks like :
<my epic powershell code>
...
exit 0
Note that without "exit 0" at the end I recieved return code 1 from my script.
We had this issue because of a "Software Restriction Policy" set up in a domain GPO. It appears that pre and post builds create a .cmd batch file in the temp folder. Here's what the logging showed me:
cmd.exe (PID = 8456) identified
C:\Users\brian\AppData\Local\Temp\tmp733425d2c0604973a90a0a175c13353e.exec.cmd
as Disallowed using default rule, Guid =
{11015445-d282-4f86-96a2-9e485f593302}
To fix this we modified the GPO that controlled the SRP so that it did not include .cmd files. After all, the goal of SRP is to block executable malware, not batch files. I may get some security blowback because of this. Hopefully someone knows a better way to fix this issue.
One possible issue is that you have to use $(ProjectDir) instead of $(ProjectPath)
When you use $(ProjectPath) it is actually: "C:\Users\....\Project\MyProject.csproj"
Versus $(ProjectDir) which is: "C:\Users\....\Project\"
Notice, that the first version is actually pointing to your project solution file... which would cause everything to fail.
Another is that that $(ProjectDir) automatically adds the trailing slash to the path. i.e. "$(ProjectDir)\test.bat" would actually translate to: "C:\Users\....\Project\\test.bat"
Also you have to make sure that you enclose all your file paths in double quotes
So the correct call would look like this:
call "$(ProjectDir)test.bat"
Other things to check out would be to make sure that the directory that the script is executing from is correct. See SO: visual studio 2012, postbuild event, bat file not creating new file (not executing)
Have you checked out the suggestions in this StackOverflow? Post Build exited with code 1
Edit
Try this:
echo Hello World
#exit 0
You need to end any commands with #exit 0 otherwise it doesn't think that it finished properly
Edit 2
Why do we use #exit 0 instead of exit 0? #Sunny has a good explanation of the At symbol - # here:
The # symbol tells the command processor to be less verbose; to only
show the output of the command without showing it being executed or
any prompts associated with the execution. When used it is prepended
to the beginning of the command, it is not necessary to leave a space
between the "#" and the command.
Essentially if you call xyz.bat by default every command in the .bat file is echoed back along with the actual output of the command. e.g.:
test.bat
echo Hello World
exit 0
Will output:
C:\>call test.bat
C:\>echo Hello World
Hello World
C:\>exit 0
C:\>
When we add a # in front of the commands, we only get the output of the commands themselves.
test2.bat
#echo Hello World
#exit 0
Will output:
C:\>call c.bat
Hello World
C:\>
#echo off is also a way to turn this off for the rest of the script. We typically do this simply to make the logs easier to read, as the text of the commands muddies the log output.

Visual Studio pre-build event; Checking exit code for each event

I have a solution with multiple projects. One project only needs to build if both two events, in the pre-build event, exit with error code 0.
So I thought I could do the following:
"C:\Path\To\Binary1.exe" & "C:\path\to\binary2.exe"
In my test scenario something goes wrong so Binary1.exe exits with a non-zero value. But visual studio goes on building the project anyway.
When I run the pre-build event commandline in cmd and echo %errorlevel% I see the exit code being non-zero.
When I only put
"C:\Path\To\Binary1.exe"
in the pre-build event, the build is stopped and en error is shown in the Error List window of Visual Studio.
I am definitely sure that Binary1.exe is exiting with a non-zero value as its also shows a messagebox prior to exit.
I can think of one solution. Binary1.exe calling Binary2.exe and exiting with a non-zero exit code when Binary2.exe exits with a non-zero exit code. But that is not really a flexible solution.
To summarize:
How can I run multiple pre-build events and stop buidling when one of the commands returns a non-zero value?
I think yuou can do as follows:
run command 1
if ERRORLEVEL 1 (
exit /b 1
)
run command 2
If the two projects are in the same solution, you can set the dependency in Visual studio.
Right-click on the solution in the solution explorer and choose "Project Dependencies".
Set the 'last' project to be depending on the first two. In this case Visual studio will build in the right order and will stop building if one of the dependencies fail to build.
(Visual Studio 2013)

How to return an error from .bat in Visual Studio (2008 SP1) project?

I have a batch file that's being run in a Visual Studio custom build step to copy files into an install directory. I want it to error out properly when the copy fails. The problems with the options I have are:
exit 1This works within the build sequence fine, but sometimes I want to use the batch file from the command line or from within another batch, and in these cases the exit causes the caller to exit as well.
exit /b 1This works nicely from the command line or from another batch file, but Visual Studio doesn't recognize that the return code wasn't 0 (i.e. it reports the project having "0 error(s)").
I came across a link that provides me with a solution: http://www.nabble.com/Re:-bjam-and-Windows-p17457249.html
Essentially it says I have to echo an error message before doing the exit /b. For instance,
echo MyProj : error : could not copy files.
Does anyone know exactly what message format triggers Visual Studio to recognize an error?
I've tried tweaking this and some work and some don't. Seems it has to match something like
.*\: .*error.*\:
Is this documented anywhere?
Thanks.
This is with Visual Studio 2008 SP1 on Windows XP Pro SP3 (in case cmd.exe has differing behaviour between Windows versions).
Regarding your actual question,
This page specifies the full syntax expected by VS as the output of the build tools.
Another thing you can try is this:
set errorlevel=1
exit /b
This basically has the same effect as what #Bill suggests. The return value of the last program ran is set to the environment variable called %errorlevel% and then when you exit cmd.exe this is the value returned from the process (which is what VS reads)
Are you quite sure you're testing this correctly?
I've just tried this batch file:
echo bla
exit /b 1
with VS2008, as a pre-build step and got this:
1>------ Build started: Project: XXXX, Configuration: Debug Win32 ------
1>Performing Pre-Build Event...
1>bla
1>Project : error PRJ0002 : Error result 1 returned from 'C:\Windows\system32\cmd.exe'.
1>Build log was saved at "file://c:\XXXXX\BuildLog.htm"
1>XXXXX - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I've also tried this with a custom build step for a file with the same exact result.
It should be noted that I am used VS2008-SP1 so that might be the difference.
Generally, the return value of a batch file is the return value of the last command executed from within the batch file.
Exit should work, but if it doesn't, for whatever reason, you could always use a helper program to set your return value.
Back in the DOS days, you could use ECHO in combination with the CHOICE command to set your return value, but alas, it's no longer part of windows.
So you could write a small program instead. Something that takes the desired return value as an argument, then sets and returns that as the return value:
#include <cstdio>
int main(int argc, char * argv[]) {
if (argc == 2) {
return strtoul(argv[1], NULL, 10);
} else {
return 0;
}
}
Then in your batch file, you just call the program with the desired return value, and jump to the end.
For some reason the exit /b 12 doesn't set the exit code when written into the post build step. The regular exit 12 would work.
So to properly return exit code from your bat file, you should write this:
call yourbat.bat
if %errorlevel% NEQ 0 exit %errorlevel%
The call command is important when running bat files, it creates a new context the bat file running in so when you run exit /b 1 in the bat file, it will exit that context, not the whole command interpreter. Then you can compare the errorlevel and exit with that.

Resources