JDK-6511002 : (process) Document the auto-quoting when creating a Windows process; add winQuote
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 6,6u24
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: windows_xp,windows_7
  • CPU: x86
  • Submitted: 2007-01-09
  • Updated: 2013-07-26
  • Resolved: 2013-07-26
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
I have a program that uses IrfanView to resize some images (see #4924909 to understand why I'm not resizing them in Java), but I discovered that ProcessImpl automatically add quotes around any element of the command array that has spaces, but doesn't already begin and end with quote marks (it gives an IllegalArgumentException if the element begins with a quote mark but doesn't end with one).


JUSTIFICATION :
This is sometimes handy, and should be documented, but some external programs (such as IrfanView) expect a quoted path as part of a parameter, but don't handle it properly if the parameter itself is quoted.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Ability to create a command line such as:
"c:\program files\irfanview\i_view32.exe" "image 1.jpg" /convert="image 2.jpg" /resize=(100,100)
ACTUAL -
Command line becomes:
"c:\program files\irfanview\i_view32.exe" "image 1.jpg" "/convert="image 2.jpg"" /resize=(100,100)
and IrfanView gives an error that it failed to load 'image 1.jpg"' (error dialog included double-quote at end, but didn't actually include the single quotes)

---------- BEGIN SOURCE ----------
public class Test {
  public static void main(String[] args) {
    try {
      Runtime.getRuntime().exec(new String[] {"c:\program files\irfanview\i_view32.exe", "image 1.jpg", "/convert=\"image 2.jpg\"", "/resize=(100,100)"});
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
(1) For IrfanView, put the resize parameter before the convert parameter.

(2) Pre-tokenize the parameter that you don't want auto-quoted (e.g. "/convert=\"image", "2.jpg\"") -- this is annoying and would not allow inserting a tab character into such a parameter.

Comments
- "/convert=\"image 2.jpg\"" + "/convert=\\\"image 2.jpg\\\""
26-07-2013

That is a duplicate. To revolve the problem , please read the final comment to JDK-6276512. In accordance with MS documentation it is not an issue. Read more here: http://msdn.microsoft.com/en-us/library/17w5ykft.aspx To achieve the desired behavior symbol ["] need to be escaped.
26-07-2013

EVALUATION See 6468220: (process) Runtime.exec(String[]) does not pass command line arguments correctly (win) As I wrote in the evaluation for that CR, We cannot change the implementation, but we should document the behavior and workaround in a place more obvious than this CR, but there is no such obvious document currently. We need a Platform Guide! At least I can document the way to use the API on Windows here: Here is a way to quote arguments to the windows process API: static boolean needsQuoting(String s) { int len = s.length(); if (len == 0) // empty string have to be quoted return true; for (int i = 0; i < len; i++) { switch (s.charAt(i)) { case ' ': case '\t': case '\\': case '"': return true; } } return false; } static String winQuote(String s) { if (! needsQuoting(s)) return s; s = s.replaceAll("([\\\\]*)\"", "$1$1\\\\\""); s = s.replaceAll("([\\\\]*)\\z", "$1$1"); return "\"" + s + "\""; }
09-01-2007