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