> -----Original Message-----
> From: Niklas Matthies [mailto:[email protected]]
> Sent: 10 November 2010 21:11
> To: [email protected]
> 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: [email protected]
For additional commands, e-mail: [email protected]