ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niklas Matthies <>
Subject Re: Apply argument wrapping with msiexec
Date Wed, 10 Nov 2010 21:10:57 GMT
This is interesting. It's caused by Java's Runtime.exec(), which
doesn't handle embedded double quotes in command line arguments
appropriately for this use case.

To pass the command line to Win32's CreateProcess function, which
takes the command line as a single string, Java needs to concatenate
the executable path and the arguments to produce that string. This is
done in ProcessImpl.start(), see below [1] for the relevant source

As can be seen from the source code, if a command line element
contains a space or tab character, the element is enclosed in double
quotes unless already fully enclosed, and disregarding potential
embedded quotes in the argument. This means that the argument

    TARGETDIR="C:\Documents and Settings\Test"

is transformed to

    "TARGETDIR="C:\Documents and Settings\Test""

which msiexec then of course fails to parse.

I'm aware of two conventions (depends on the individual application)
for embedding quotes within quoted arguments under Windows: by
escaping with backslash, or by doubling the embedded quotes:

    "TARGETDIR=\"C:\Documents and Settings\Test\""
    "TARGETDIR=""C:\Documents and Settings\Test"""

Msiexec doesn't seem to support either, at least not for property
settings, so quoting the complete argument cannot be used as a

I think it would be appropriate to file a bug report for
Runtime.exec(). If its implementation would only add quotes if the
string didn't already contain quotes around the whitespace, there
wouldn't be a problem.

As a workaround, I would suggest writing the command to a temporary
batch file and execute that.

-- Niklas Matthies

[1] From version 1.32, 06/03/22,
    from my version of JDK 1.6:

    StringBuilder cmdbuf = new StringBuilder(80);
    for (int i = 0; i < cmd.length; i++) {
        if (i > 0) {
            cmdbuf.append(' ');
        String s = cmd[i];
        if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
            if (s.charAt(0) != '"') {
                if (s.endsWith("\\")) {
            } else if (s.endsWith("\"")) {
                /* The argument has already been quoted. */
            } else {
                /* Unmatched quote for the argument. */
                throw new IllegalArgumentException();
        } else {

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message