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
code

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
workaround.

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 ProcessImpl.java 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) != '"') {
                cmdbuf.append('"');
                cmdbuf.append(s);
                if (s.endsWith("\\")) {
                    cmdbuf.append("\\");
                }
                cmdbuf.append('"');
            } else if (s.endsWith("\"")) {
                /* The argument has already been quoted. */
                cmdbuf.append(s);
            } else {
                /* Unmatched quote for the argument. */
                throw new IllegalArgumentException();
            }
        } else {
            cmdbuf.append(s);
        }
    }


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@ant.apache.org
For additional commands, e-mail: user-h...@ant.apache.org

Reply via email to