United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6511002 : (process) Document the auto-quoting when creating a Windows process; add winQuote

Details
Type:
Enhancement
Submit Date:
2007-01-09
Status:
Resolved
Updated Date:
2013-07-26
Project Name:
JDK
Resolved Date:
2013-07-26
Component:
core-libs
OS:
windows_xp,windows_7
Sub-Component:
java.lang
CPU:
x86
Priority:
P4
Resolution:
Not an Issue
Affected Versions:
6,6u24
Fixed Versions:

Related Reports
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:

Sub Tasks

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
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. 
                                     
2013-07-26
- "/convert=\"image 2.jpg\""
+ "/convert=\\\"image 2.jpg\\\""
                                     
2013-07-26
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 + "\"";
    }
                                     
2007-01-09



Hardware and Software, Engineered to Work Together