简体   繁体   中英

PowerShell command not getting executed using java Process class. While all other commands are working fine

I am trying to execute below command using java Process class but it's not giving me any response or neither its effecting which it should do.

But when I am executing the command directly on PowerShell its working fine only it's not working using java code. I have tried other PowerShell commands, and all are working fine accept this one.

It's a command to disable indexing of a drive.

Output its only printing the command and in response of isAlive() method call it replies with false.

Command: powershell.exe Get-WmiObject -Class Win32_Volume -Filter "DriveLetter='I:'" | Set-WmiInstance -Arguments @{IndexingEnabled=$False} powershell.exe Get-WmiObject -Class Win32_Volume -Filter "DriveLetter='I:'" | Set-WmiInstance -Arguments @{IndexingEnabled=$False}

isAlive: false

There is nothing more in the code I am just calling this method from my main class that's it like classObject.disableIndexing("D")

Note I am executing the same using admin rights only. Please help.

public String disableIndexing(String driveLetter) {
        
    String returnVal="";
    String command = "powershell.exe Get-WmiObject -Class Win32_Volume -Filter \"DriveLetter='"+driveLetter+":'\" | Set-WmiInstance -Arguments @{IndexingEnabled=$False} ";
    try {   
        System.out.println(command);
        Process p = Runtime.getRuntime().exec(command);
        p.waitFor();
        String line1="";
        String line="";
        BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
        while ((line1 = br.readLine()) != null) {
                    System.out.println(line1);
            if(!line1.isEmpty())
            System.err.println(line1);
        }
        System.out.println(p.isAlive());
        if(p.exitValue()==0) {
            returnVal="Indexing changed Successfully";
                }else {
            returnVal="Your Drive is Not Responding Try After Some Time";
            }
    }catch(Exception e) {
        e.printStackTrace();
            
    }
    return returnVal;
        
}

The problem here is likely that | is interpreted by the default shell (eg. cmd.exe) before being passed to powershell.exe .

To work around this, use the -EncodedCommand command line switch to safely pass the command to powershell.exe :

public String disableIndexing(String driveLetter) {
    String driveLetter = "D";
    String powerShellCommand = "Get-WmiObject -Class Win32_Volume -Filter \"DriveLetter='" + driveLetter + ":'\" | Set-WmiInstance -Arguments @{IndexingEnabled=$False}";

    // Base64-encode the UTF16LE representation of the command
    byte[] powerShellBytes = powerShellCommand.getBytes(StandardCharsets.UTF_16LE);
    String encodedCmd = new String(Base64.getEncoder().encode(powerShellBytes));

    String command = "powershell.exe -EncodedCommand " + encodedCmd;

    try {
        // proceed the same as before ...
    }
    catch (Exception e) {
        // ...
    }

    return returnVal;
}

hey guys I got the solution. But even I didn't understand how this worked. So, what I did is while coping my command from one method to another method I accidently left the 2 extra slashes on my String command and executed it. And it worked. Actual Command: String command = "powershell.exe Get-WmiObject -Class Win32_Volume -Filter \"DriveLetter='H:'\" | Set-WmiInstance -Arguments @{IndexingEnabled=$False} " It was not working.

Command which worked: String command = "powershell.exe Get-WmiObject -Class Win32_Volume -Filter \\\"DriveLetter='H:'\\\" | Set-WmiInstance -Arguments @{IndexingEnabled=$False} " I still not able to understand how it worked. because in actual PowerShell command it shouldn't have that back slash before and after DriveLetter.

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