包含多个空格的参数上的Runtime.exec

时间:2011-07-13 22:46:47

标签: java runtime exec spaces

任何人都可以进行以下运行吗?

public class ExecTest {
  public static void main(String[] args) {
    try {
      //Notice the multiple spaces in the argument
      String[] cmd = {"explorer.exe", "/select,\"C:\\New      Folder\\file.txt\""};

      //btw this works
      //String cmd = "explorer.exe /select,\"C:\\New Folder\\file.txt\"";

      //and surprisingly this doesn't work
      //String[] cmd = {"explorer.exe", "/select,\"C:\\New Folder\\file.txt\""};

      //Update: and (as crazy as it seems) the following also worked
      //String[] cmd = {"explorer.exe", "/select,\"C:\\New", "Folder\\file.txt\""};

      Runtime.getRuntime().exec(cmd);
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

使用Java 6.在Vista x64下测试。顺便说一句,获取执行的字符串(你必须使用exec的String版本来获取它)并在Vista的开始菜单的 Search 字段中使用它将按预期运行。登记/> 任何帮助将不胜感激。我疯了......!

更新: 我为我的帖子指出的第二个奇怪的东西添加了一个解决方案,这两个版本的exec表现不同。解决方案基于prunge的答案。 Thnx再次。

8 个答案:

答案 0 :(得分:6)

好的,这不只是一个更新,而是一个答案,所以我把它归为一个。根据我能找到的所有信息,理论上应该做到以下几点:

  

String [] cmd = {“explorer.exe”,“/ select,\”C:\ New“,”“,”“,”“,”“,”“,”“,”文件夹\文件。 TXT \ “”};

多个空格已被分解为空字符串,并使用了exec的数组版本。 使用上面的数组,我在java.lang.ProcessImpl的第50-75行调试了循环,最后构造了一个字符串。结果字符串是:

explorer.exe / select,“C:\ New Folder \ file.txt”

这是作为第一个参数传递给ProcessImpl的native create方法(第118行同一个类),因为它似乎无法正常运行此命令

所以我猜这一切都在这里结束......可悲的是。

Thnx prunge指出java bug。 感谢每个人的时间和兴趣!

答案 1 :(得分:5)

除非命令行非常简单,否则始终使用Runtime.exec(String []),而不是Runtime.exec(String)。

答案 2 :(得分:5)

奇迹,它有效!

不要问我为什么,但是当我在互联网上经过一段时间的神经破坏研究后,我已经接近放弃并使用临时批处理文件作为解决方法,我忘了添加/ select,该命令的参数,以及谁会想到,以下内容适用于我的Win 7 32Bit系统。

String param = "\"C:\\Users\\ME\\AppData\\Local\\Microsoft\\Windows\\Temporary Internet Files\\\"";
try {
    String[]commands = new String[]{"explorer.exe", param};
    Process child = Runtime.getRuntime().exec(commands);
} catch (IOException e1) {
    System.out.println("...");
}

一般解决方案:

prunge在他的帖子(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6511002)中提到的bug数据库的解决方案对我来说很好。

<强>原因:

显然问题在于在实际执行命令字符串之前对java所做的一些字符的评论。 你必须通过标记你的命令字符串来自己做评论,以防止错误的java文件生效并使一切变得混乱。

如何解决:

所以,在我的情况下,我必须执行以下操作(将命令字符串标记,以便字符串中没有空格):

String param[] = {
    "explorer.exe",
    "/select,C:\\Users\\ME\\AppData\\Local\\Microsoft\\Windows\\Temporary",
    "Internet",
    "Files\\"};

try {
    Process child = Runtime.getRuntime().exec(param);
} catch (IOException e1) {
    System.out.println("...");
}

正如你所看到的,我基本上在一个空格出现的地方开始了一个新的字符串,因此“Temporary Internet Files”变成了“Temporary”,“Internet”,“Files”。

答案 3 :(得分:2)

首先使用new File(pathName).canExecute()检查它是否可执行

修改

public static void runAll(String... cmd)
{
    for(String s : cmd)
    {
        try
        {
            Runtime.getRuntime().exec(cmd);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

然后您就可以使用它:runAll("explorer.exe", "taskmgr.exe");

答案 4 :(得分:1)

可能是一个Java错误。看到: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6511002

由于好奇心进行了一些调试,我认为java.lang.ProcessImpl中的事情正在变得松散(参见构造函数)。注意到当它实际调用底层Windows API时,字符串已变为

explorer.exe“/ select,”c:\ New Folder \ test.txt“”

这可以解释为什么,至于变通方法,请参阅bug数据库链接。

答案 5 :(得分:1)

字符,-&和双倍空格,都是噩梦!

此处所揭示的所有答案均未通过"\\NAS\media\Music\Artistes\E\Earth, Wind & Fire\1992 - The eternal dance - Vol. 1 (1971-1975)('Vol.1'和'(1971')之间的双倍空格。

除了编写临时批处理文件之外别无选择:

   void openFolderOf( Album album ) {
      try {
         final String path = album._playList.getParent();
         final File batch = File.createTempFile( getClass().getSimpleName(), ".bat" );
         try( PrintStream ps = new PrintStream( batch )) {
            ps.println( "explorer.exe \"" + path + '"' );
         }
         Runtime.getRuntime().exec( batch.getAbsolutePath());
      }
      catch( final Throwable t ) {
         t.printStackTrace();
      }
   }

注意:在cmd.exe上,行explorer "\\NAS..."运行良好,但Runtime.exec()和ProcessBuilder不行。

答案 6 :(得分:0)

对于需要显示/选择命令的特定情况,我使用cmd / c start来解决Windows引用噩梦:

String[] cmd = {"cmd", "/c", "start explorer.exe /select," + path};

其中path是来自File对象的绝对路径。

答案 7 :(得分:-1)

解决文件此问题的简单方法是java.awt.Desktop自1.6 示例:

   Desktop.getDesktop().open(new File(fullFileName));