Today I had to add a task to an Apache Ant file. The command line should have been something like
myprogram --param1 --param2 path\somefile 2> path\logfile
The problem with this was that if I used something like the following for this
<exec executable="$(myprogram)"
<arg value="--param1">
<arg value="--param2">
<arg path="$(somefile)">
<arg value="2>">
<arg path="$(logfile)">
</exec>
all arguments were quoted, so the command looked like this:
myprogram "--param1" "--param2" "path\somefile" "2>" "path\logfile"
which is not bad and especially nice if you have spaces in your files/path, but destroys the pipe to the logfile (instead, the program thinks there are two additional file arguments "2>" and "path\logfile").
I worked around this by calling a batch script instead that only wants the files as parameters, but I wondered: Is it possible to do this without such a workaround?
When you run "myprogram --param1 --param2 path\somefile 2> path\logfile", the arguments to your program end at "2>". File redirection is an operation of your shell, which isn't being used from within ant. If you look at the docs for the ant exec task, you'll see that it supports redirection via the output attribute.
Have you tried <arg line="..." />?
The ant exec task has an output parameter where you could specify the log file without requiring the command line piping, combined with the parameter append to determine if the output file should be overwritten or appended to.
I had an equal problem as the topic starter did. On a java execution command line I needed to add source files as separate arguments, not as one argument with quotes around them.
I used the <arg value="..." /> tag, but using the <arg line="..." /> as nullptr suggested solved my problem.
Related
The reference for the command line arguments (http://msdn.microsoft.com/en-us/library/ms164311%28v=vs.100%29.aspx) shows that for console and file logger there is a parameter called ShowTimestamp which prefixes messages with a timestamp.
How does this work? Reproduction file:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<Target Name="Build">
<Message Text="Message" />
</Target>
</Project>
Call:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /clp:ShowTimestamp;ShowEventId dummy.msbuild.xml
I can see the ShowEventId displayed in the output but the timestamp is missing. I've tried this for /flp as well, no timestamp.
I tried other params like PerformanceSummary etc, all fine. I tried setting tool version to 12.0, same result.
Using reflector I realized that ShowTimestamp is used only inside ParallelConsoleLogger class, so the only way to see timestamp (without writing own logger) is to to force msbuild to use parallel logger, i.e. we need to specify /m switch.
Resulting command line for your sample will be
msbuild.exe /clp:ShowTimestamp;ShowEventId /m dummy.msbuild.xml
If computer has single core (like, virtual build machine), then /m will work like /m:1 and will use simple logger, but you can work around this by specifying /m:2 for example - it will still use the only available core, BUT it will use ParallelConsoleLogger.
I am having a task to find whether the clearcase folder has any changes or not.
<Target Name="CheckChanges" Returns="ItemsFromFile">
<Exec Command="cleartool find "$(FolderPath)" -version "{brtype($(StreamName)) && created_since($(FromDate))}" -print >> Changes.log" />
<ReadLinesFromFile
File="Changes.log" >
<Output
TaskParameter="Lines"
ItemName="ItemsFromFile"/>
</ReadLinesFromFile>
</Target>
<Target Name="Build">
<!-- This target should be executed only when Changes.log file has contents -->
<Target>
If the $(FolderPath) has changes then the contents will be available in Changes.log.
What i would like to do is if the changes.log file contains some lines then run another task Build should run.
How to execute a target based on condition that the file has contents?
What i would like to do is if the changes.log file contains some lines then run another task Build should run.
The issue is that you are redirecting the result of your cleartool find with '>>'.
The first execution of the job will initialize the Changes.log file, and you could setup another job which test for the existence of that file (see MSBuild conditions) with a non-zero size in order to run. (As bit like "verify the existence of a folder using the msbuild extension pack?")
But the second execution would simply add lines (if there are changes), or keep the Changes.log file unchanged.
That means "Changes.log" would still "have content" even though the cleartool find didn't find any changes.
Using '>' instead of '>>' would solve that, since it would generate an empty Changes.log file if the cleartool find doesn't detect any change, or generate a non-empty file if changes are detected.
I have created a custom .proj file that builds my web site project's solution. It seems to all work correctly and it produces an output. However, when I put it on the server, I got an error about "/Default.aspx is not precompiled and cannot be requested". After some digging I discovered that indeed the precompiled aspx files were not precompiling. In the output from msbuild, I found a call to aspnet_compiler:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v /WebApplication -p WebApplication\ -f -fixednames Output_PublishedWebsites\WebApplication\
When I run this command directly, it generates everything just fine.
How can I get my msbuild wrapper to perform this correctly?
My msbuild task looks like this:
<MSBuild Projects="$(SolutionFile)"
Properties="OutDir=$(OutputRoot);
Configuration=$(AspNetConfiguration)"
Targets="Build" />
I solved this by using the <AspNetCompiler /> task.
I'm attempting to automate a roundtrip install and uninstall of a set of MSI files (generated by WiX) from a pack of sample programs. For some reason, a .MSI file that's perfectly happy to install on a double click generates:
This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.
when I invoke it with MSIEXEC in the following manner:
<ItemGroup>
<_SampleMsi Include="$(_ArtifactsPathAcceptanceSamples)\**\*.msi" />
</ItemGroup>
<Exec Command="$(WixDir)\smoke "%(_SampleMsi.Identity)""/>
<!--Guarantee precondition even if cleanup didn't work-->
<Exec Command="msiexec -passive -norestart -x "%(_SampleMsi.Identity)"" IgnoreExitCode="true" />
<Exec Command="msiexec -norestart -i "%(_SampleMsi.Identity)"" />
<!--Uninstall of every sample should also always work-->
<Exec Command="msiexec -passive -norestart -x "%(_SampleMsi.Identity)"" />
The same problem also happens when I try to uninstall based on the Product Id GUID:-
msiexec -passive -norestart -x FC7445BB-7E1D-4E36-A42A-CFA56263E453
What gives?
Just removed .\ prep-ending the filename and it worked.
Do not take the text of the message literally. About all you should be concluding is that misexec is treating some part of your command as a filename, and it didn't get to load and process the entirety of it to its satisfaction. Whether that's because the path was too long, permissions were refused, or any number of other conditions only limited by your imagination (most of the KB articles appear to pertain to Installer cache issues, which is generally the GUID-based syntax or patching/upgrading options)
You're missing the braces from the GUID, fool. I mean, you did know there are braces on the GUID even if msiexec /? doesn't tell you or show you, right?!
i.e. you need to replace FC7445BB-7E1D-4E36-A42A-CFA56263E453 with {FC7445BB-7E1D-4E36-A42A-CFA56263E453}
(I had stopped trusting/reading the outputs and was considering it a possibility that the GUID was resolving to a cached MSI which msiexec was unhappy with for the same reason that it appeared to be unhappy with the installation syntax which is what all the KB articles in this space tend to talk about.)
Your path contains relative jumps which, despite having a net length of <160 chars, have a gross length >160 chars so the underlying file APIs are choking. People like writing generic error messages that are misleading.
You can fix it by replacing Identity above with FullPath in each batching expression used.
Another way to remedy it is to use a WorkingDirectory with the Exec of msiexec
As part of my Ant integration test script, I run an MSBuild build (just executing the msbuild.exe), and it works fine in the positive cases. However, Ant doesn't recognize when the msbuild build fails. How can I make it work?
EDIT:
I can msbuild by executing the executable:
<target name="executeMsbuild">
<exec command="C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe /t:build-for-tests ${csharp.dir}\msbuild.xml"/>
</target>
Provide failonerror attribute to exec.
Also provide a property formsbuild.exe path.
Also pass command line arguments as args
<target name="executeMsbuild">
<property name="msbuild-prog"
location="C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe"
/>
<exec
executable="${msbuild-prog}"
failonerror="true"
>
<arg value="/t:build-for-tests"/>
<arg file="${csharp.dir}/msbuild.xml"/>
</exec>
</target>
Using failonerror=true will give you an instant "BUILD FAILED" in case
of an error and will be sufficiant in most cases.
For a more sophisticated error handling use =
the try task from the Antelope tasksuite (1), which will give you a
try/catch/finally (2) as in java.
Antelope has also a limit task (3), which is a taskcointainer where other tasks
are put in and provided with a timeout.
Limit may be combined with try or use alone
In case someone mentions AntContrib, it's another ant task suite, that has
equivalent tasks as Antelope ,but it seems the development of AntContrib
has stopped (4)
(1) Antelope Tasksuite
(2) Manpage try task
(3) Manpage limit task
(4) Antelope <> AntContrib