2

I'm working on a Java macro that runs within another program as part of a computational fluid dynamics package. One thing that annoys me about this package is that the monitor going on standby seems to pause the simulations. But seeing as I have access to these macros I thought that I would add a section to change my power settings to keep the monitor awake.

I'm rather new to Java and so I found the easiest way of doing this would be to call PowerScript to do the actual settings changes. So far, I'm able to read the current state of the settings using the following (hidden for readability since this part works).

        String command;
        command = "powershell.exe  $p = Get-CimInstance -Name root\\cimv2\\power -Class win32_PowerPlan -Filter \"IsActive=\'True\'\"; $p.ElementName";
        Process powerShellProcess = Runtime.getRuntime().exec(command);
        powerShellProcess.getOutputStream().close();
        String line;
        BufferedReader stdout = new BufferedReader(new InputStreamReader(
          powerShellProcess.getInputStream()));
        line = stdout.readLine();
        System.out.println("The current power mode is: "+line);
        stdout.close();

The next step would be to set the power settings using something like this:

     String powerMode = "Balanced";
     command = "powershell.exe  $p = Get-CimInstance -Name root\\cimv2\\power -Class win32_PowerPlan -Filter \"ElementName=\'"+powerMode+"\'\"; Invoke-CimMethod -InputObject $p[0] -MethodName Activate";
     System.out.println(command);
     powerShellProcess = Runtime.getRuntime().exec(command);
     powerShellProcess.getOutputStream().close();
     new InputStreamReader(powerShellProcess.getInputStream());

The command prints properly as

powershell.exe  $p = Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan -Filter "ElementName='Balanced'"; Invoke-CimMethod -InputObject $p[0] -MethodName Activate

When running that command (minus the "powershell.exe", of course) in PowerShell works perfectly, but when calling it from Java results in the -Filter "ElementName='Balanced'" returning null.

Can anyone tell me why the filter argument is not being passed properly? It works fine when filtering by "IsActive" as shown in the first part but not when filtering by "ElementName". Could it have something to do with the escape sequence nightmare around the element name?

2
  • Welcome to SO ! You may want to shorten the code present in your question : the important factor is that Get-CimInstance -Name root\cimv2\power -Class win32_PowerPlan -Filter "ElementName='Balanced'"; doesn't work via java. Commented Mar 24, 2015 at 17:43
  • On Unix, it would have been because you use fragile and dangerous Runtime.exec(String) instead of the safe and robust Runtime.exec(String[]) (or the equivalent but more powerful ProcessBuilder). I don't know enough about the Windows process model though. Worst case, maybe .exec(new String[] { "cmd", "/c", command }); Commented Mar 24, 2015 at 18:21

1 Answer 1

3

Powershell is very finicky on its handling of quotes on the command line. The easy solution is to send in the query as

-Filter 'ElementName=\"Balanced\"'

For more info on this see https://connect.microsoft.com/PowerShell/feedback/details/376207/executing-commands-which-require-quotes-and-variables-is-practically-impossible

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! It works great using the following command to switch the quote types and pass the added backslash: command = "powershell.exe $p = Get-CimInstance -Name root\\cimv2\\power -Class win32_PowerPlan -Filter \'ElementName=\\\""+powerMode+"\\\"\'; Invoke-CimMethod -InputObject $p[0] -MethodName Activate";
Unfortunately all "feedback" links regarding PowerShell seem to be broken now, they just redirect to bing. The solution is: You need 3 backslashes to escape quotes, so something like -Filter "name like '%somename%'" (works fine in PowerShell directly) turns into -Filter \\\"name like '%somename%'\\\" if you want to use it in Java.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.