How to access local env variables from ANT file - batch-file

I have this ANT file that calls a batch file to set the environment variables, before these environment variables are referred to in the ANT script.
So my batch file (set_env.bat) contains:
REM ------ ECLIPSE ------
SET DIR_ECLIPSE=C:\Eclipse
SET DIR_ECLIPSE_MARS=%DIR_ECLIPSE%\eclipse-dsl-mars-2-win32
SET DIR_DEST=C:\mydsl\generated
Then my ANT script will call it like this:
<target name="setvars" >
<exec executable="cmd">
<arg value="/c"/>
<arg value="set_env.bat"/>
<arg value="-p"/>
</exec>
</target>
<property environment="env"/>
<property name="tool" value="${env.DIR_ECLIPSE_MARS}" />
<property name="destDir" value=${env.DIR_DEST}" />
<target name="create_run_jar">
<copy file="${env.DIR_ECLIPSE_MARS}/plugins/org.eclipse.xtext_2.9.1.v201512180746.jar"
todir="${destDir}/myDsl_lib" />
</target>
I keep on getting an error saying the file cannot be found and when I print the log via , I get "[echo] ${env.DIR_ECLIPSE_MARS}". So this means that the env vars are not set.
During copy, it displays this log:
D:\mydsl\antbuild.xml:129: Warning: Could not find file D:\mydsl\${env.DIR_ECLIPSE_4_5_2}\plugins\org.eclipse.xtext_2.9.1.v201512180746.jar to copy.
I execute the setvars target first followed by the create_run_jar.

Related

List of files located in text file to be send as parameter to WinSCP in script mode

I've to create solution that is based on WinSCP and windows batch script. Below are tasks the script has to do:
Save list of files from remote directory, to file located on machine where batch script is run.
Run WinSCP in command mode (/command) using WinSCP script passed as parameter (/script=name_of_script_file.txt) and get files (get command) from previously generated list.
The most important is to get file list, save it and pass names of files located in created file to WinSCP to get them.
How to implement this?
There's no easy way to implement this using WinSCP scripting only. It's possible, see the very end of my answer, but it may not be an ideal solution.
Why do you do this in two steps? Why don't you directly download the directory?
winscp.com /command ^
"option batch abort" ^
"option confirm off" ^
"open scp://user:password#example.com/" ^
"get /path/*" ^
"exit"
If you really need the list (e.g. for some further processing), you can instead of getting a list of files in the directory, get a list of actually downloaded files.
Enable the XML logging, and get the list from the XML log.
winscp.com /xmllog=log.xml /command ^
....
You get a log like:
<?xml version="1.0" encoding="UTF-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="user#host" start="2015-01-30T06:45:57.008Z">
<download>
<filename value="/path/file1.txt" />
<destination value="C:\path\file1.txt" />
<result success="true" />
</download>
<download>
<filename value="/path/file2.txt" />
<destination value="C:\path\file2.txt" />
<result success="true" />
</download>
</session>
If you need a plain-text list, you can use the XSLT to convert it (e.g. download.xslt):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:winscp="http://winscp.net/schema/session/1.0">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match='winscp:download[winscp:result[#success="true"]]/winscp:filename'>
<xsl:value-of select="#value"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
To process it, use any XSLT processor:
Microsoft msxsl.exe (deprecated, but available from Internet Archive)
msxsl.exe log.xml download.xslt
Libxml2 xsltproc.exe:
xsltproc.exe download.xslt log.xml
And you get:
/path/file1.txt
/path/file2.txt
See Transforming XML Log to Text Output Using XSLT Transformation.
To answer your actual question. If you really insist on getting a file list and downloading files according to it, I suggest you use the WinSCP .NET assembly from a PowerShell script.
Use the Session.ListDirectory to retrieve a contents of a remote directory.
See the Session.ListDirectory documentation and its example code.
For recursive listing, you can also use the Session.EnumerateRemoteFiles.
Iterate the results and call the Session.GetFiles for every file.
See the Session.GetFiles documentation and its example code.
If the simple scripting is your preference:
The only way to obtaining a plain text list of remote files reliably, is to use the XML logging to capture an output of the ls scripting command:
winscp.com /xmllog=log.xml /command ^
"option batch abort" ^
"option confirm off" ^
"open scp://user:password#example.com/" ^
"ls /path" ^
"exit"
You get a log like:
<?xml version="1.0" encoding="UTF-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="user#host" start="2015-01-30T07:08:27.749Z">
<ls>
<destination value="/path" />
<files>
<file>
<filename value="." />
<type value="d" />
<modification value="2014-07-28T07:06:49.000Z" />
<permissions value="rwxr-sr-x" />
</file>
<file>
<filename value=".." />
<type value="d" />
<modification value="2015-01-23T12:22:44.000Z" />
<permissions value="rwxr-xr-x" />
</file>
<file>
<filename value="file1.txt" />
<type value="-" />
<size value="1306091" />
<modification value="2015-01-29T23:58:12.000Z" />
<permissions value="rw-rw-rw-" />
</file>
<file>
<filename value="file2.txt" />
<type value="-" />
<size value="88" />
<modification value="2007-11-17T22:40:43.000Z" />
<permissions value="rw-r--r--" />
</file>
</files>
<result success="true" />
</ls>
</session>
Again, use the XSLT to convert the XML log to a plain-text list of files:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:winscp="http://winscp.net/schema/session/1.0">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match='winscp:file[winscp:type/#value="-"]/winscp:filename'>
<xsl:value-of select="#value"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
You get:
file1.txt
file2.txt
To get WinSCP script to download files according to a plain-text list, see scripting example Uploading a list of files. It's for an upload, but just replace the put with the get and reverse an order of arguments to turn it to a download.
Note that the /command parameter does not enter a "command" (scripting?) mode. It's for passing scripting commands on a command line (as used in my answer). You are using a script file (/script). There's no point adding an empty /command parameter to it.
See the documentation of WinSCP scripting command-line parameters.

Execute Ant targets within environment set up by .cmd file

I want to kick off an .exe from an Ant script. The .exe has a requirement that a .cmd file be run first to prep the environment. To be clear: if I open a console, run the .cmd first, and then my .exe, all is well. I'm working in Windows 7.
This is what I currently have but it isn't working, I assume because the .cmd runs as its own process, and when control returns to Ant I've lost that scope so the next target runs and doesn't know anything about what happened in the .cmd file. Or at least that's what appears to be happening.
I've messed around with different cmd switches, spawn true/false, etc. but nothing really seems to be working and I am not sure what to Google for to see a working example of this situation.
<target name="-someTarget">
<exec executable="cmd" spawn="false">
<arg value="/c" />
<arg value="somefile.cmd" />
</exec>
<exec executable="some.exe" spawn="false">
<arg value="-whatever" />
<arg value="somevalue" /> <!-- etc. -->
</exec>
</target>
This is my workaround for now, but I would rather keep everything in my Ant script if possible.
<target name="-someTarget">
<exec executable="cmd" spawn="false">
<arg line='/c somefile.bat "c:\some path\" an-arg "c:\another path\.txt" "c:\and another\.log"' />
</exec>
</target>
somefile.bat:
call %1\somefile.cmd
call %1\some.exe %2 %3 %4
You can call both on the same command line
<exec executable="cmd">
<arg line="/c somefile.cmd &"/>
<arg value="some.exe"/>
<arg value="-whatever"/>
<arg value="somevalue"/>
<!-- etc. -->
</exec>
The reason for the <arg line> is that you can't supply just & to <arg value> (at least that didn't work for me.
The 'arg line=' method suggested by Slav works as long as the DOS call command is used:
<exec executable="cmd">
<arg line="/c call some.cmd & call some.exe" />
</exec>

Running a Batch file with ant 'build.xml'

I am trying to run a batch file called 'sparql.bat' by using ant build.xml. The last line in the batch file is -
java %JVM_ARGS% -Dlog4j.configuration="%LOGGING%" -cp "%JENA_CP%" arq.sparql --data=\apache-jena-2.10.0\test.ttl --query=\apache-jena-2.10.0\testing.rq
Where %JVM_ARGS% is -Xmx1024M and the other things can also be replaced.
I am trying to run this using an ant build.xml, "--data=\apache-jena-2.10.0\test.ttl --query=\apache-jena-2.10.0\testing.rq" are the arguments.
I have prepared the build.xml like this-
<?xml version="1.0"?>
<project name="apache-jena-2.10.0" basedir="." default="notify">
<target name="notify">
<java JVM_ARGS="-Xmx1024M" Dlog4j.configuration="%LOGGING%" cp="C:\apache-jena-2.10.0\lib\*" arq.sparql="%*">
<arg data="C:\apache-jena-2.10.0\test.ttl"/>
<arg query="\apache-jena-2.10.0\ASKTest.rq"/>
<classpath>
<pathelement location="."/>
</classpath>
</java>
</project>
Can somebody please help me to write a build.xml file which can execute this?
Thanks
Somsuvra
Try something more along these lines:
<java classname="arq.sparql">
<arg value="--data=C:\apache-jena-2.10.0\test.ttl"/>
<arg value="--query=C:\apache-jena-2.10.0\testing.rq"/>
<jvmarg value="-Xmx1024M"/>
<jvmarg value="-Dlog4j.configuration=log4j.properties”/>
<classpath>
<pathelement location="C:\apache-jena-2.10.0\lib"/>
</classpath>
</java>
Final solutions is -
<?xml version="1.0"?>
<project name="apache-jena-2.10.0" basedir="." default="notify">
<target name="notify">
<java classname="arq.sparql" fork="true">
<arg value="--data=C:\apache-jena-2.10.0\test.ttl"/>
<arg value="--query=C:\apache-jena-2.10.0\ASKTest.rq"/>
<jvmarg value="-Xmx1024M"/>
<classpath>
<pathelement location="C:\apache-jena-2.10.0\lib\jena-core-2.10.0.jar"/>
<pathelement location="C:\apache-jena-2.10.0\lib\jena-arq-2.10.0.jar"/>
<pathelement location="C:\apache-jena-2.10.0\lib\log4j-1.2.16.jar"/>
</classpath>
</java>
</target>
</project>
Now my question is instead of writing all the .jar files seperately is there any way of specifying them in a single line.
Thanks and regards
Somsuvra
You could replace the pathelement elements with a fileset. Something like this:
<fileset dir="C:\apache-jena-2.10.0\lib">
<include name="**/*.jar"/>
</fileset>

ant exec task output includes the args?

In windows 8.1 when I run this, I get the exec command appended to the top of the output file.
<exec executable="cmd" os="Windows 8" spawn="false" dir="${basedir}" output="${build.out}" error="${build.err}">
<arg value="/c"/>
<arg line="${build.bat}" />
<arg value="-p"/>
</exec>
The output file looks like this:
C:\yaya\the_base_dir>node C:\yaya\haha\pjsCompile.js
//here begins the output I expected....
How do I remove the command from the output? Why is it there?
If it is helpful, this is the build.bat:
node C:\yaya\haha\pjsCompile.js
Change the build.bat to this:
#node C:\yaya\haha\pjsCompile.js
or to this:
#echo off
node C:\yaya\haha\pjsCompile.js

WIX invoking Batch file in InstallExecution Sequence

I am new to WIX and I am trying to invoke a batch file from my WIX installer.
MyBatch.bat contains a simple Copy of a Text file from c:\ to D:\
I am unable to invoke the batch file. Below is my code.
Please help me out.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductName='Test Product' ?>
<?define ProductVersion='1.0.0.0' ?>
<?define ProductCode='b7bc7c6f-9a4e-4973-be84-eca8e3427c97'?>
<?define UpgradeCode='06a81104-1e30-463d-87e1-e8a79b4c682a'?>
<?define Manufacturer='Respond'?>
<Product Id="$(var.ProductCode)" Language="1033" Version='$(var.ProductVersion)' Name='Respond'
Manufacturer='$(var.Manufacturer)' UpgradeCode='$(var.UpgradeCode)'>
<Package InstallerVersion='200' Compressed='yes' />
<Media Cabinet='media1.cab' EmbedCab='yes' Id ='1' />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id='ProgramFilesFolder'>
<Directory Id='INSTALLDIR' Name='$(var.ProductName)'>
<Component Id='ProductComponent' Guid='b11556a2-e066-4393-af5c-9c9210187eb2'>
<File Id='Calc' DiskId='1' Source='C:\WINDOWS\system32\calc.exe'/>
<File Id='my_batch_script' Name='MyBatch.bat' DiskId='1' Source='MyBatch.bat' />
</Component>
</Directory>
</Directory>
<Directory Id='ProgramMenuFolder'>
<Directory Id='ApplicationProgramsFolder' Name='$(var.ProductName)'>
<Component Id='MainExecutable' Guid='EDED00D8-2465-46CA-86D6-B20DE921EFA6'>
<Shortcut Id='ShortcutCalc' Description='$(var.ProductName)' Name ='Calculator of Windows'
Target='[INSTALLLOCATION]Calc.exe' WorkingDirectory='INSTALLLOCATION'/>
<RemoveFolder Id='ApplicationProgramsFolder' On='uninstall'/>
<RegistryValue Root='HKCU' Key='Software\$(var.Manufacturer)\$(var.ProductName)' Type ='multiString'
Name='installed' Value='1' KeyPath='yes'/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Title='SetupProject1' Level='1' Id ='AppFeature'>
<ComponentRef Id='ProductComponent' Primary='yes'/>
<ComponentRef Id='MainExecutable'/>
</Feature>
<Property Id='WIXUI_INSTALLDIR' Value='INSTALLDIR' ></Property>
<WixVariable Id='WixUILicenseRtf' Overridable='yes' Value='License.rtf'/>
<?include CustomActions.wxi?>
<UI>
<?include UISequence.wxi?>
<?include Dialogs.wxi?>
</UI>
<CustomAction Id="BatchCmd" Property="ThePath" Value="[INSTALLDIR]MyBatch.bat" />
<CustomAction Id="BatchRun" Property="ThePath" ExeCommand='"[INSTALLDIR]MyBatch.bat"' Return='asyncWait' Impersonate="yes"/>
<InstallExecuteSequence>
<Custom Action="BatchCmd" After="InstallFiles" >Not Installed </Custom>
<Custom Action="BatchRun" After="BatchCmd">Not Installed </Custom>
</InstallExecuteSequence>
</Product>
</Wix>
This worked for me.
<CustomAction Id="test"
ExeCommand="[INSTALLDIR]MyBatch.bat"
Directory="INSTALLDIR" Execute="deferred" Return="asyncWait"/>
<InstallExecuteSequence>
<Custom Action="test" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
It seems you're solving your problem with the wrong tool. If the file to copy is a part of your application, you should author a Component with this File inside. Otherwise, if you need just to copy some external file already present on a target system, you should author a CopyFile element, nesting it under Component element.
I agree with Yan, you solve your task the wrong way.
As for batch files, they are not executed on its own like an .exe, it is cmd.exe which reads the bat file and executes it line by line.
To run a batch file, you should run it this way:
cmd.exe /c batch.bat
Add your CustomAction defnition as given below. Make sure that Return="ignore" if you are not returning anything from bat file.
<CustomAction Id="RunBat" Directory="your_directory"
ExeCommand='"c:\test\test.BAT"'
Execute='deferred' Impersonate='no' Return='ignore'/>
Also in the installExecuteSequence sequence add the action before InstallFinalize
<InstallExecuteSequence>
<Custom Action="RunBat" Before="InstallFinalize">
NOT (REMOVE~="ALL")
</Custom>
</InstallExecuteSequence>

Resources