如何用Java获取并操作系统进程?

经过测试,发现了些问题,修改下代码。

声明:

本篇文章主要记录如何使用 Java查询Windows电脑的进程,并解析结果,显示于浏览器上。

使用SpringBoot没有写前端框架,简单的生成一个Table显示在浏览器上。后续有空,就写个前端,使用仪表盘显示。

内容:

代码主要使用了dos的几个命令:

查找进程列表命令:tasklist
根据pid删除进程命令:tasklist /f /pid 123456
查询当前系统的内存命令:wmic ComputerSystem get TotalPhysicalMemory

代码:

查询进程代码:

 public static List<List<String>> taskList(){
        try{
            Process p = Runtime.getRuntime().exec("taskList");
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(),"gbk"));
            List<String> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();

            String line = "";
            int i = 0;

            Pattern titlePattern = Pattern.compile("[\u4e00-\u9fa5|a-zA-Z0-9]*");
            List<Integer> list = new ArrayList<>();
            while((line = br.readLine())!=null){
                if("".equals(line))
                    continue;;
                if(i==0){
                    Matcher m = titlePattern.matcher(line);
                    while(m.find()){
                        String group = m.group(0);
                        if("".equals(group))
                            continue;
                        keys.add(group);
                    }
                }else if(i>1){
                    values.add(line);
                }else{
                    int k = 0;
                    list.add(0,0);
                    for(int j=0;j<line.length();j++){
                        if(line.charAt(j)=='='){
                            list.set(k,list.get(k)+1);
                        }else{
                            k++;
                            list.add(k,0);
                        }
                    }
                }
                i++;
            }

            List<String> parseValues = new ArrayList<>();
            for (String value : values) {
                int start = 0;
                int l = 0;
                for (int k : list) {
                    int n = 0;
                    if(value.endsWith("暂缺") && l == 4)
                        n = 2;
                	//这若是含有暂缺两字,就会出现问题,比其他的少了两个字符。所以会出现数组越界。
                	
                    String v = value.substring(start, start + k);
                    if(v.endsWith("K")){
                        String memory = v.replaceAll(",", "").replaceAll("K", "").trim();
                        v = Integer.parseInt(memory)/1024 + "MB";
                    }
                    parseValues.add(v);
                    start = start + k + 1;
                    l++;
                }
            }

            int start = 0 ,end = parseValues.size();
            int le = keys.size();
            List<List<String>> rtnl = new ArrayList<>();

            while(end>0){
                List<String> s = parseValues.subList(start,start + le);
                rtnl.add(s);
                start = start + le;
                end-=le;
            }

            rtnl.sort(new MemorySortCompare());
            rtnl.set(0,keys);
            return rtnl;
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

根据命令查询出内容,再针对内容进行解析,将每个每列进行匹配。
分为了标题与数据两块,并根据占用内存进行倒序排列,代码如下:

 static class MemorySortCompare implements  Comparator{
        @Override
        public int compare(Object o1, Object o2) {
            List<String> l = (List<String>)o1;
            List<String> l1 = (List<String>)o2;
            String s = l.get(4);
            String s1 = l1.get(4);
            
            //2021年2月12日修改;
			//同样的,将含有暂缺的数据都放到最后
			if("暂缺".equals(s))
                s = "-1";
            if("暂缺".equals(s1))
                s1 = "-1";
  
            String s2 = s.replaceAll(",",
                    "").replaceAll("MB", "").trim();
            String s3 = s1.replaceAll(",", "").replaceAll("MB", "").trim();
            int m = Integer.parseInt(s2);
            int m1 = Integer.parseInt(s3);
            return Integer.compare(m1, m);
        }
    }

查询内存代码:

    public static String showMemory(){
        String exec = "wmic ComputerSystem get TotalPhysicalMemory";
        try{
            Process p =  Runtime.getRuntime().exec(exec);
            Scanner scanner = new Scanner(p.getInputStream(),"gbk");
            int i = 0;
            String memorys=  "";

            Pattern pattern = Pattern.compile("[0-9]*");
            while(scanner.hasNextLine()){
                memorys = scanner.nextLine().trim();
                if(memorys.length() > 0 && pattern.matcher(memorys).matches())
                    break;
                i++;
            }

            return memorys;

        }catch(Exception e){
            e.printStackTrace();
        }
        return "";
    }

因为改代码查出来后数据规则不统一,只能根据不同的逻辑进行匹配。
主要为了获取内存,所以正则匹配0-9就行了。

关闭进程代码:

    @RequestMapping("/close")
    public String close(HttpServletRequest request){
        String pid = request.getParameter("PID");
        try{
            Runtime.getRuntime().exec("taskkill /f /pid "+pid);
        }catch(Exception e){
            e.printStackTrace();
        }
        return  "已成功终止PID为"+pid+"的进程!";
    }

访问当前进程接口后,会将数据绘制成表格,然后点击关闭进程按钮,就可以根据PID关闭进程。

绘制表格代码:

public static String processRender(List<List<String>> l){
        if(l.isEmpty())
            return null;
        String table = "<table>";
        String memory = TaskList.showMemory();
        double d = Double.parseDouble(memory);
        d = d/1024/1024/1024;
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数
        table += "<tr><td>当前电脑的内存为:"+df.format(d)+"G</td></tr>";
        String headTr = "<tr>";
        List<String> heads = l.get(0);
        StringBuilder headTd = new StringBuilder();
        for (String s : heads) {
            headTd.append("<td>").append(s).append("</td>");
        }
        headTd.append("<td>占用率</td>");
        headTd.append("<td>操作</td>");
        headTr += headTd+"</tr>";
        StringBuilder tr = new StringBuilder();
        for (int i=1;i<l.size();i++) {
            List<String> ls = l.get(i);
            StringBuilder td = new StringBuilder();
            String pid = "";
            String curMemory = "";
            int k = 0;
            for (String s : ls) {
                td.append("<td>").append(s).append("</td>");
                if(k==1){
                    pid = s;
                }
                if(k==4)
                    curMemory = s;
                k++;
            }
            curMemory = curMemory.replace("MB", "");
            double d1 = d*1024;
            Matcher m = PatternUtil.matchChinese(curMemory, "[\u4e00-\u9fa5]");
            if(!m.find()){
                td.append("<td>").append(df.format(((Double.parseDouble(curMemory))/d1)*100)).append("%</td>");
            }else{
                td.append("<td>0.00%</td>");
            }
            td.append("<td>").append("<a target='_blank' href='/close?PID=").append(pid).append("'>关闭进程</a>").append("</td>");
            tr.append("<tr>").append(td).append("</tr>");
        }
        table+=headTr;
        table+=tr;
        table += "</table>";
        return table;
    }

同时显示了内存以及计算每个进程所占用内存的占用率。

在这里插入图片描述
点击关闭进程后就会跳转到另一个页面(现在懒得写那么多前端)

在这里插入图片描述
这样QQ.exe就被关闭了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值