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

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.

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.

VS2019 Pre and Post build events always fails with code 1

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 -_-

Visual Studio Post Build Event if exists

I want to call a batch file in my post build step in Visual Studio. Locally the batch file exists, just the command
call "$(SolutionDir)PostBuildSen.bat" "$(TargetDir)" "$(TargetName)"
correctly calls and executes the batch file.
However when I want to check if the batch file exists first (since others will use the same Post Build Event), I get the error
:VCEnd" exited with code 255.
The command is
if exists "$(SolutionDir)PostBuildSen.bat" call "$(SolutionDir)PostBuildSen.bat" "$(TargetDir)" "$(TargetName)"
The Diagnostic output tells me
2> Done executing task "Exec" -- FAILED.
How do you handle this?
The Solution Directory contains a folder with an underscore, i.e. \Dev_Main\ and I have read that for the batch file that is to be called at least that doesn't work. However I am not sure if that is the issue with folders as well and how to cope with it. Also, since the call command works, I am not sure this is the problem.
Furthermore, if I replace the call with cmd /C, the exit code is 1 and the (minmal) output tells me
1>The filename, directory name, or volume label syntax is incorrect.
Also, I will add this as a custom command to a CMakeLists file later on, so the solution needs to work with that.
Thanks to Hans Passant's comment, I solved the problem. The query for the file needs to be if exist rather than if exists.

Why is an argument passed to a Perl script not working on running it from within a batch file?

I wrote a batch called pippo.bat for launching a program with an argument. However, it fails in getting such argument. In other words, it acts as I don't give it any argument.
pippo.bat
#echo off
mode con: cols=150 lines=5000
title Link Setting
echo.
echo LINK SETTING
echo.
cd /d E:\Program Files (x86)\pippo\bin
pippoedit.ovpl –f C:\Work\pippo.xml
pause
What's wrong?
You're executing pippoedit.ovpl –f C:\Work\pippo.xml.
Note the extension, .ovpl, which isn't registered as an executable. This means you let the OS figure out and start the application associated with that extension, and start that program with that filename as argument. Here, a small repro:
#echo off
foo.txt bar.txt
This starts Notepad or whichever application is associated with the .txt extension and displays the file foo.txt.
When you do this, Windows doesn't do anything with the arguments beyond the first. Instead you should start the application directly, and pass it the arguments:
pippoedit.exe pippoedit.ovpl –f C:\Work\pippo.xml
Or whatever the executable is called.

Windows Batch File - Batch File stops executing mid way after a command that takes a while to complete

Following are the contents of the file "vs.bat"
call "C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat"
call path.bat
dea usev bis
cd ana
call b-env-i.bat
When I execute this batch file, execution stops after the following step.
dea usev bis
Can anyone please help in pointing out what went wrong here and how I can get all the commands to execute. Note that the aforementioned command (dea usev bis) works fine (both in the batch and if executed separately). dea is the name of the executable and "usv bis" are runtime parameters to the "dea" exe.
I'm running Windows 7.
Clarification:
When I run vs.bat, after the third call "dea usev bis" has executed successfully, the batch file stops executing further. That is both the following calls (which are part of VS.bat) don't get executed
cd ana
call b-env-i.bat
Note that the call "dea usev bis" takes around 20 secs to execute, both when run individually and when run as part of the script.
Update:
I've tried paxdiablo's suggestions, with the following results:
[C:\dea]for %i in (dea.cmd) do #echo %~$PATH:i
ECHO is on.
[C:\dea]for %i in (dea.bat) do #echo %~$PATH:i
ECHO is on.
[C:\dea]for %i in (dea.exe) do #echo %~$PATH:i
C:\dea\bin\dea.exe
[C:\dea]where dea.exe
C:\dea\bin\dea.exe
C:\dea\bin\dea.exe.1
C:\dea\bin\dea.exe.ia64
When I run it explicitly via the following, I still encounter the same issue
c:\dea\bin\dea.exe usev bis
And, as I said earlier, changing the script to call dea does not fix the issue either.
Is there anything else that I can try?
It looks like you're trying to call another batch/script file which, if you leave off call, will simply be chained to rather than called (chained to, in this context, means it doesn't return). I'd suggest changing that line to:
call dea usev bis
By way of example, consider the scripts go2.cmd:
#echo off
echo %1
and go.cmd:
#echo off
call go2 1
go2 2
echo 3
Executing go will only give you:
1
2
because the go2 2 line chains to, rather than calls that script. The call go2 1 line, however, works fine.
And, even if you have a dea.exe file, that does not necessarily mean it's the one being run. Your script calls dea so leaves the choice as to what actually gets run to the shell (searching the path, trying different extensions and so on).
To check whether or not the thing you're actually calling is a batch file or not, you can do the following. First, execute the following commends:
echo %PATH%
for %i in (dea.cmd) do #echo %~$PATH:i
for %i in (dea.bat) do #echo %~$PATH:i
for %i in (dea.exe) do #echo %~$PATH:i
(or I think you can just use where dea* if you're running Win 7+, see here for details).
This will show you if there is a dea.cmd/bat/exe in your path, and tell you where in the path the relevant directories are. If there is a script version, it may exist in the path before the exe version. You can simply examine your %PATH% environment variable to figure out which directory comes first.
Second, if you have the exe in c:\dea\bin, try running that explicitly from your script with:
c:\dea\bin\dea.exe usev bis
If that returns okay, it adds support to the fact a script version is being used instead.
Thirdly, you could just change the script as suggested (add call) and see if that fixes it. If it is referencing a script, that will fix it.
If none of those work (and this appears to be the case based on your response that dea is definitely an exe file), you need to start looking into exactly where the failure occurs. This can be done by placing an echo statement in between every single line so that you can see what's causing the issue. In other words, something like:
echo DEBUG a & time <nul:
call "C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat"
echo DEBUG b & time <nul:
call path.bat
echo DEBUG c & time <nul:
dea usev bis
echo DEBUG d & time <nul:
cd ana
echo DEBUG e & time <nul:
call b-env-i.bat
echo DEBUG f & time <nul:
That will both give you timings for the things that do work and hopefully make it obvious what's not working.

Resources