简体   繁体   中英

How to pass context menu parameters to Java ProcessBuilder

I am using Java ProcessBuilder to open a file with a specific program on windows.

That itself works fine, with the following code:

ProcessBuilder p = new ProcessBuilder();
p.command("C:\\Program Files (x86)\\...\\program.exe", file.getAbsolutePath());

What I want to do is to invoke the functionality of a file context menu entry from that program which looks like this:

"C:\Program Files (x86)\...\program.exe" /Enqueue "%1"

How do I have to pass those parameters to the process builder?

I already tried the following, none of which worked:

p.command("C:\\Program Files (x86)\\...\\program.exe","/Enqueue","%1",next.getAbsolutePath());
p.command("C:\\Program Files (x86)\\...\\program.exe","Enqueue","%1",next.getAbsolutePath());
p.command("C:\\Program Files (x86)\\...\\program.exe","Enqueue","\"%1\"",next.getAbsolutePath());
p.command("C:\\Program Files (x86)\\...\\program.exe","/Enqueue","\"%1\"",next.getAbsolutePath());

"Not working" in this case meaning that the program is launched, but nothing happens (the file is not even opened).

If I switch them around in this order: (program, file, parameters) then the file is opened correctly, but the additional parameters do nothing, as if they weren't even there.

What is the correct way to translate those parameters into the ProcessBuilder command?

The first thing you need to do, is make "C:\\Program Files (x86)\\...\\program.exe" /Enqueue "%1" into an array of [C:\\Program Files (x86)\\...\\program.exe, /Enqueue, %1] otherwise ProcessBuilder will try and execute the whole String as a single command, which really isn't what you want.

Maybe something like...

String cmd = "\"C:\\Program Files (x86)\\...\\program.exe\" /Enqueue \"%1\"";
StringBuilder sb = new StringBuilder(cmd);
List<String> commands = new ArrayList<>(10);
while (sb.length() > 0) {
    if (sb.charAt(0) == '"') {
        int nextIndex = sb.indexOf("\"", 1);
        if (nextIndex < 0) {
            nextIndex = sb.length();
        } else {
            nextIndex++;
        }
        commands.add(sb.substring(1, nextIndex).replace("\"", ""));
        sb.delete(0, nextIndex);
    } else if (sb.charAt(0) == ' ') {
        if (sb.length() > 1 && sb.charAt(1) != '"') {
            int nextIndex = sb.indexOf(" ", 1);
            if (nextIndex < 0) {
                nextIndex = sb.length();
            }
            commands.add(sb.substring(1, nextIndex));
            sb.delete(0, nextIndex);
        } else {
            sb.delete(0, 1);
        }
    }
}
System.out.println(commands);

Which will print...

[C:\Program Files (x86)\...\program.exe, /Enqueue, %1]

There's probably a really neat regular expression you could use to help with this, but this will get the job done, more or less.

Next, you want to replace %1 with the file you want to open. Now, you can do this within the previous code, which would be more efficient, but for demonstration purposes...

String[] parameters = {"Hello kitty"};
for (int index = 0; index < commands.size(); index++) {
    String value = commands.get(index);
    if (value.startsWith("%")) {
        int parameter = Integer.parseInt(value.substring(1)) - 1;
        if (parameter < parameters.length) {
            commands.set(index, parameters[parameter]);
        }
        // You might want to think about what you want to do if you have
        // more parameter marks then you do have actual parameter values
    }
}
System.out.println(commands);

Which prints out...

[C:\Program Files (x86)\...\program.exe, /Enqueue, Hello kitty]

Which you can now pass to ProcessBuilder , for example...

ProcessBuilder pb = new ProcessBuilder(commands);

Now, you could do the String substitution at many different points in the code, in many different ways, this is just an example of one

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM