Visual Studio MSBuild exec task - output window buffer flush - visual-studio

My build process involves an Exec task that runs a console program.
<Target Name="TestTask" AfterTargets="AfterBuild">
<Exec Command='program.exe" />
</Target>
The program's output is shown in the "output" window, but only after the task has finished (all at once). How can I see the output gradually? It's a long-running task that reports a lot of thing as it goes...
UPD: found a relevant question with a workaround: MSBuild AfterBuild messages not showing real-time

Visual Studio MSBuild exec task - output window buffer flush
I`d like provide your a workaround for this issue, but I am not sure if it exactly meets your requirements.
To accomplish this, you could try putting the execute command in a batch file and invoking the batch file instead. Not very elegant but might do the trick. The batch file like:
start /d "<PathForTheProgram.exe>" program.exe
Or you can use Windows power-shell to start the program.exe directly:
<Target Name="TestTask" AfterTargets="AfterBuild" >
<Exec Command="powershell start-process "<PathForEXE>\program.exe "" />
</Target>
The different is that the program's output is shown in the command prompt window not inside in the Visual Studio output window.
Hope this helps.

Related

Redirected output file remains open after devenv.exe returns

I have a .bat file with the following two commands:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\..\IDE\devenv" plugin\proj1-vs15.sln /rebuild "Release" /project plugin\proj1-vs15.vcxproj /projectconfig "Release|x64" 1>vcbuild.log 2>&1
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\..\IDE\devenv" plugin\proj2-vs15.sln /rebuild "Release" /project plugin\proj2-vs15.vcxproj /projectconfig "Release|x64" 1>vcbuild.log 2>&1
The first command completes successfully but the second one immediately fails with the message "The process cannot access the file because it is being used by another process."
If I use a different filename for the redirected output in the second command then both commands complete without error.
I haven't had this problem with Visual Studio 2015 or any earlier versions, only with VS 2017.
Why is the redirected output file remaining open after the first devenv command has completed?
In my actual use-case having each execution of devenv.exe use a different filename for the redirected output would be inconvenient. Is there some way of ensuring that the output file is closed before the .bat file advances to the next command?
Any child process that devenv spawns inherits the redirection handle, So if after debenv returns any of its child process is still open the file remains locked so CMD can not open vcbuild.log file the second time. The solution is to put both build commands in a redirected compound block.
(
devenv <First Project Arguments>
devenv <Second Project Arguments>
)>"vcbuild.log" 2>&1

Determine if program.exe is available before using it in an Exec Task?

According to Microsoft's Exec Task, it runs the specified program or command by using the specified arguments:
Command - Required String parameter.
The command(s) to run. These can be system commands, such as attrib,
or an executable, such as program.exe, runprogram.bat, or setup.msi.
This parameter can contain multiple lines of commands. Alternatively,
you can put multiple commands in a batch file and run it by using this
parameter.
We are currently using a CustomBuild like the following:
<CustomBuild Condition="'$(Platform)'=='Win32'" Include="rdrand.asm">
<Message>Building and assembling rdrand.asm</Message>
<Command>ml.exe /c /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo"$(IntDir)rdrand-x86.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdrand-x86.obj;%(Outputs)</Outputs>
</CustomBuild>
We want to switch to NASM and an Exec Task because it provides a single set of sources for Windows and Linux. It also allows us to provide ASM for Windows phones and tablets when appropriate, like PMULL and PMULL2. If NASM is not available, then we will use the standby C/C++ implementation.
Note: we don't want the user to do anything. We don't want them to select something, and we don't want them setting defines. Asking the user to do something means we have to field user questions. We want things to "just work" for users; F5 under Visual Studio should "just work" as far as the user is concerned.
My first question is, is Exec Task the right tool for the job? My scond question is, how can we determine if nasm.exe is available from within MSBuild? Here, "available" means its on-path so we can call it.
Hard to tell with certainty whether Exec is the right tool but it's definitely the way to call external programs so it's perfectly usable here I guess.
Here, "available" means its on-path so we can call it.
Better make sure it can be called (as in, not missing dependencies and not 64bit on a 32bit machine for example), not just whether it's found. Standard way of doing this: just try to run it:
<Target Name="CheckNasmIsCallable">
<!-- Redirect standard output to avoid clutter, IgnoreExitCode
as this is just a check so should not lead to actual errors. -->
<Exec Command="nasm.exe -h > NUL" IgnoreExitCode="True">
<Output TaskParameter="ExitCode" PropertyName="NasmExitCode" />
</Exec>
</Target>
<Target Name="WantsToRunNasm" DependsOnTargets="CheckNasmIsCallable">
<Message Text="Nasm found" Condition="'$(NasmExitCode)' == '0'" />
<Message Text="Nasm not found" Condition="'$(NasmExitCode)' != '0'" />
</Target>

Flush output after every line in output window with external build tool

I'm wondering if it's possible to tell Visual Studio to print the output of an external build tool as it gets it.
I have an external build tool (JSIL) called from my .csproj file like so:
...
<Target Name="AfterBuild" Condition="$(JSIL) != 'building'">
<Exec Command="JSILc.exe $(SolutionPath)" />
</Target>
...
This works fine--the output goes to the Visual Studio output window. However, it seems that Visual Studio buffers the output of the command until it exits and then prints that output in its entirety all at once.
Since the JSIL compiler takes a relatively long time and has quite a bit of output, I would like for the output window to reflect that while building.
JSIL outputs commands by printing to stdout or stderr, but manually .Flush()ing these streams doesn't seem to affect the output window. Is there some special API that I need to call to update Visual Studio about the progress of a custom build tool?
Thanks!

bat script only runs first line?

When I copy/paste the lines below into a cmd window it executes without a problem.
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
msbuild proj\projsln /p:Configuration=Debug
proj\proj\bin\Debug\proj.exe my args
However when I save it as DoStuff.bat I get the message below (which is the text from executing vcvars32.bat), then nothing else. It does not build my project and obviously doesn't run the newly built executable.
Why doesn't it and how do I have it run all three commands?
>"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
Setting environment for using Microsoft Visual Studio 2010 x86 tools.
Use CALL to call another batch file.
Well, there has to be a reason it isn't continuing. Is it that the command is waiting for some input? Thats all that I can think of. Try re-directing the output of the batch file to a log and see what is going on.
Alternatively, split the batch file into separate batch files and put a CALL before each call to the batch file.

MSBuild: Colored cucumber output

When I run cucumber from the windows command line I get colored output (currently using ANSICON).
When I use the following MSBuild target, run from the command line, I don't get colored output
<Target Name="Tests_Functional_Run">
<Exec Command="bundle exec cucumber" />
</Target>
Any ideas how I can get colored output in MSBuild?
First of all, I just had to read this question to see what "Colored Cucumber" was...
Are you building the project in Visual Studio, or using MSBuild from a command line? I ask because MSBuild from a command line puts out all sorts of coloured output, but I've never seen colour in the VS output window.
The coloration is an artifact of the "display module" (for lack of a better term at hand). The Windows console is sensitive to the type of message it displays from command-line output.
You'd need to make or find a VS add-in to colorize the Output pane. Or copy the text into a capable editor and use its colorizing capabilities.
Your terminal needs to support ANSI color. We use something called ANSICon here, it can be set up so it installs itself in all cmd shells and gives color output for cucumber.

Resources