Executing programs

Being a batch file replacement language, XSharper of course can execute other executable files. And also in a more convenient way than traditional batch files, as output redirection and argument escaping (a major annoyance when writing Windows batch files) is handled w/o hacks and temporary files.

<shell>echo Hello world!</shell>

Output may be redirected to a variable or output stream

<shell >echo This goes to a real console, no redirection</shell>
<shell outTo="^out">echo This goes to a redirected output stream!</shell>
<shell outTo="^info">echo This goes redirected to info stream!</shell>

By default the output is expected to be text in default encoding (encoding can be changed using encoding attribute). It's also possible to redirect in binary mode, using binary="1" attribute.

There are different modes of command execution, specified via mode attribute:

comspec execute cmd /c program
batch save the shell command as a batch file, execute it, and then delete the batch file
direct the first argument is expected to be a name of an executable file
shellExecute use shellExecute, useful for direct opening of Word documents, or printing (specify verb='print') and so on
auto If verb is empty, use comspec otherwise shellexecute

Exit code may be saved to a variable via exitcodeTo attribute. By default, unless ignoreExitCode attribute is set, exception is thrown if the exit code is non-zero.

XSharper also provides assistance with argument escaping, by automatically escaping arguments with spaces inside with double quotes, and escaping " and other special characters with \ (which works fine with most applications but unfortunately not all as command line parsing in Windows is poorly standardized).

For example, the code below creates a temp batch file, and executes it with parameters, which are automatically escaped as needed. Parameters may be specified via <param> sub-element, which may also accept arrays, as demonstrated in the following example:

<set name="batch">
	@echo off
	echo args=[%*]
	set count=0
	:loop
		if "%~1"=="" goto end
		echo arg[%count%]=%1
		set /a count=%count%+1
		shift
		goto loop
	:end
</set>

<shell mode='batch' value="${batch}">
	<param>No-spaces</param>
	<param>This param is with spaces</param>
	<param>This is also with spaces</param>
</shell>
<print />

<!-- Create array of 3 strings -->
<set arr="${=new {'param1', 'param 2', 'param 333' }}"/>

<shell mode='batch'>
	${batch}
	<param>Non-array</param>
	<param switch="/xx">${arr}</param>
</shell>

The script outputs

args=[No-spaces "This param is with spaces" "This is also with spaces"]
arg[0]=No-spaces
arg[1]="This param is with spaces"
arg[2]="This is also with spaces"

args=[Non-array /xx param1 "param 2" "param 333"]
arg[0]=Non-array
arg[1]=/xx
arg[2]=param1
arg[3]="param 2"
arg[4]="param 333"