Get list of processes on Windows in a charset-safe way

后端 未结 4 1891
别那么骄傲
别那么骄傲 2020-12-01 19:27

This post gives a solution to retrieve the list of running processes under Windows. In essence it does:

String cmd = System.getenv(\"windir\") + \"\\\\system         


        
4条回答
  •  感情败类
    2020-12-01 19:51

    Can break this into 2 parts:

    1. The windows part
      From java you're executing a Windows command - externally to the jvm in "Windows land". When java Runtime class executes a windows command, it uses the DLL for consoles & so appears to windows as if the command is running in a console
      Q: When I run C:\windows\system32\tasklist.exe in a console, what is the character encoding ("code page" in windows terminology) of the result?

      • windows "chcp" command with no argument gives the active code page number for the console (e.g. 850 for Multilingual-Latin-1, 1252 for Latin-1). See Windows Microsoft Code Pages, Windows OEM Code Pages, Windows ISO Code Pages
        The default system code page is originally setup according to your system locale (type systeminfo to see this or Control Panel-> Region and Language).
      • the windows OS/.NET function getACP() also gives this info

    2. The java part:
      How do I decode a java byte stream from the windows code page of "x" (e.g. 850 or 1252)?

      • the full mapping between windows code page numbers and equivalent java charset names can be derived from here - Code Page Identifiers (Windows)
      • However, in practice one of the following prefixes can be added to achieve the mapping:
        "" (none) for ISO, "IBM" or "x-IBM" for OEM, "windows-" OR "x-windows-" for Microsoft/Windows.
        E.g. ISO-8859-1 or IBM850 or windows-1252

    Full Solution:

        String cmd = System.getenv("windir") + "\\system32\\" + "chcp.com";
        Process p = Runtime.getRuntime().exec(cmd);
        // Use default charset here - only want digits which are "core UTF8/UTF16"; 
        // ignore text preceding ":"
        String windowsCodePage = new Scanner(
            new InputStreamReader(p.getInputStream())).skip(".*:").next();
    
        Charset charset = null;
        String[] charsetPrefixes = 
            new String[] {"","windows-","x-windows-","IBM","x-IBM"};
        for (String charsetPrefix : charsetPrefixes) {
            try {
                charset = Charset.forName(charsetPrefix+windowsCodePage);
                break;
            } catch (Throwable t) {
            }
        }
        // If no match found, use default charset
        if (charset == null) charset = Charset.defaultCharset();
    
        cmd = System.getenv("windir") + "\\system32\\" + "tasklist.exe";
        p = Runtime.getRuntime().exec(cmd);
        InputStreamReader isr = new InputStreamReader(p.getInputStream(), charset);
        BufferedReader input = new BufferedReader(isr);
    
        // Debugging output
        System.out.println("matched codepage "+windowsCodePage+" to charset name:"+
                charset.name()+" displayName:"+charset.displayName());
        String line;
        while ((line = input.readLine()) != null) {
               System.out.println(line);
        }
    

    Thanks for the Q! - was fun.

提交回复
热议问题