> -----Original Message-----
> From: Niklas Matthies [mailto:ml_ant-u...@nmhq.net] 
> Sent: 10 November 2010 21:11
> To: user@ant.apache.org
> Subject: Re: Apply argument wrapping with msiexec
> 
> 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.

Will look to do that.
 
> As a workaround, I would suggest writing the command to a temporary
> batch file and execute that.
> 
> -- Niklas Matthies

For the moment since I only need to extract 1 msi, it's fine being stuffed into 
1 long command line using exec. But will experiment with generating a batch 
file anyway for future use.

 
> [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);
>         }
>     }

That is interesting, it makes the assumption that if the arg doesn't start with 
quotes and has whitespace, then it needs quoting. A simple if crude fix would 
be to swap the first 2 tests.

Thanks for looking into it in detail.

--
Regards,
Darragh Bailey

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

Reply via email to