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

发布于 2024-11-19 16:58:07 字数 862 浏览 7 评论 0原文

我怎样才能进行以下运行?

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 字段中使用它,将按预期运行。

How can I make the following run?

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();
    }
  }
}

Using Java 6. Tested under Vista x64. By the way, taking the string that gets executed (you'll have to use the String version of exec to get it) and using it in the Search field of Vista's start menu will run as expected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

兰花执着 2024-11-26 16:58:07

好吧,这不仅仅是一个更新,也是一个答案,所以我将其作为一个答案归档。根据我能找到的所有信息,理论上应该执行以下操作:

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 行同一类),它似乎无法正确运行此命令

所以我想这一切都结束了......可悲的是。

感谢 prunge 指出 java bug。
感谢大家的时间和兴趣!

Ok, this is not simply an update but also an answer so I'm filing it as one. According to all information I could find, the following should theoretically do it:

String[] cmd = {"explorer.exe", "/select,\"C:\New", "", "", "", "", "", "", "Folder\file.txt\""};

The multiple spaces have been broken into empty strings and the array version of exec is used.
Using the above array, I debugged the loop in lines 50-75 of java.lang.ProcessImpl where a string is finally constructed. The resulting string was:

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

This is what is passed as the 1st argument to ProcessImpl's native create method (line 118 same class), which as it seems fails to run properly this command.

So I guess it all ends here... sadly.

Thnx prunge for pointing out the java bug.
Thnx everyone for their time and interest!

说好的呢 2024-11-26 16:58:07

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

Always use Runtime.exec(String[]), not Runtime.exec(String) unless the command line is extremely simple.

我的鱼塘能养鲲 2024-11-26 16:58:07

奇迹,它有效!

不要问我为什么,但是当我在互联网上进行了相当长一段时间的令人伤脑筋的研究后,几乎要放弃并使用临时批处理文件作为解决方法是,我忘记将 /select 参数添加到命令中,谁会想到,以下内容适用于我的 Win 7 32 位系统。

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 在他的帖子中提到的错误数据库的解决方案(https://bugs.java.com/bugdatabase/view_bug?bug_id=6511002)对我来说效果很好。

原因:

显然,问题在于 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("...");
}

如您所见我基本上在出现空格的地方开始一个新字符串,因此“临时 Internet 文件”变成了“临时”、“Internet”、“文件”。

A miracle, it works!

Don't ask me why, but when i, after quite a while of nerve-wrecking research in the internets, was close to give up and use a temporary batch file as a workaround, i forgot to add the /select, parameter to the command, and, who would have thought, the following works on my Win 7 32Bit System.

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("...");
}

General Solution:

The solution of the bug-database mentioned by prunge in his post (https://bugs.java.com/bugdatabase/view_bug?bug_id=6511002) worked fine for me.

Reason:

Apparently the problem lies with the commenting of some characters done by java which it does before actually executing the command string.
You have to do the commenting yourself by tokenizing your command string, to prevent the faulty java one to spring into action and mess everything up.

How to fix:

So, in my case i had to do the following (tokenizing my command string, so that no spaces are left inside the string):

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("...");
}

As you can see i basically started a new String wherever a space occured, so "Temporary Internet Files" became "Temporary","Internet","Files".

独夜无伴 2024-11-26 16:58:07

首先使用 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”);

Use new File(pathName).canExecute() first to check whether it's executable or not

EDIT:

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

and then you can use it like: runAll("explorer.exe", "taskmgr.exe");

旧人九事 2024-11-26 16:58:07

字符 、-& 和双空格,所有这些组合起来就是一场噩梦!

这里暴露的所有答案都失败了“\\NAS\media\Music\Artistes\E\Earth, Wind & Fire\1992 - 永恒之舞 - 第 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。

The characters ,-& and double spaces, all combined are a nightmare!

All the answers exposed here failed for "\\NAS\media\Music\Artistes\E\Earth, Wind & Fire\1992 - The eternal dance - Vol. 1 (1971-1975) (double space between 'Vol. 1' and '(1971').

I have no other choice than writing a temporary batch file:

   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();
      }
   }

Note: on cmd.exe, the line explorer "\\NAS..." works well but not with Runtime.exec() nor ProcessBuilder.

つ低調成傷 2024-11-26 16:58:07

可能是 Java 错误。看:
https://bugs.java.com/bugdatabase/view_bug?bug_id=6511002

出于好奇做了一些调试,我认为事情在 java. lang.ProcessImpl(参见构造函数)。注意到当它实际调用底层 Windows API 时,字符串已变成

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

因此这可能解释了原因,至于解决方法,请参阅错误数据库链接。

Could be a Java bug. See:
https://bugs.java.com/bugdatabase/view_bug?bug_id=6511002

Did a bit of debugging out of curiosity, I think things are becoming unstuck in java.lang.ProcessImpl (see the constructor). Noticed that when it got to actually calling the underlying Windows API the string had turned into

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

So that might explain why, as for workarounds see the bug database link.

孤独岁月 2024-11-26 16:58:07

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

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

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

For your specific case of needing the reveal/select command, I get around the windows quote nightmare by using cmd /c start:

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

Where path is the absolute path from a File object.

一笑百媚生 2024-11-26 16:58:07

更好的方法是使用 ProcessBuilder 对象:

 Process p;
 p = new ProcessBuilder("/Applications/Sublime Text.app/Contents/MacOS/sublime_text", homeDir + _CURL_POST_PUT_CMDS).start();
 int exitValue = p.waitFor();
 if (exitValue != 0){
    System.out.println("Error to open " + homeDir + _CURL_POST_PUT_CMDS);
 }

A better way to do it would be using ProcessBuilder object:

 Process p;
 p = new ProcessBuilder("/Applications/Sublime Text.app/Contents/MacOS/sublime_text", homeDir + _CURL_POST_PUT_CMDS).start();
 int exitValue = p.waitFor();
 if (exitValue != 0){
    System.out.println("Error to open " + homeDir + _CURL_POST_PUT_CMDS);
 }
差↓一点笑了 2024-11-26 16:58:07

解决文件问题的简单方法是 java.awt.Desktop 从 1.6 开始
例子:

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

Simple way to resolve this problem for files is java.awt.Desktop Since 1.6
Example:

   Desktop.getDesktop().open(new File(fullFileName));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文