1. 程式人生 > >獲取 window任務欄已經打開應用程序窗口(也就是任務管理器中前臺進程)的圖標

獲取 window任務欄已經打開應用程序窗口(也就是任務管理器中前臺進程)的圖標

public name rgs ges pub 集合 icon pid 完整

獲取 window任務欄已經打開應用程序窗口(也就是任務管理器中前臺進程)的圖標

1.功能描述

獲取到window任務欄已經打開的應用程序的窗口圖標。如下:(要獲取到QQ,瀏覽器,文件夾的圖標,但是任務欄中隱藏的圖標不顯示)

技術分享

2.使用技術及工具

JAVA,JNA,eclipse。

需要去下載JNA的包(一個是jna.jar,一個時jna-platform.jar);包的下載在文章結尾提供地址。

技術分享

3.實現思路

(1).一個window任務欄打開的應用程序也就是一個前臺進程,所以先通過JNA獲取所有任務欄進程(.exe文件名稱,文件路徑,PID)(從.EXE文件中可以獲得圖片),這時獲得進程還包括一些非窗口(非前臺應用)進程,需要使用第二步驟過濾掉。
(2).從JNA中枚舉出所有的窗口句柄,並且通過窗口句柄獲得PID。
(3).遍歷第一步驟獲得的進程獲得元素的PID,當元素的PID在第二步驟獲得的集合中時,則從此元素的.exe文件中獲得圖片。

4.實現代碼

(1)獲取窗口的句柄進程PID

 1 public class EnumWindow {
 2     public static Set<Integer> getTaskPID() {
 3         User32 user32 = User32.INSTANCE;
 4         Set<Integer> set=new HashSet<Integer>();
 5         IntByReference i=new IntByReference();//放PID
 6         user32.EnumWindows(new
User32.WNDENUMPROC() { 7 public boolean callback(HWND h, Pointer p) { 8 user32.GetWindowThreadProcessId(h, i);獲取窗口的PID 9 if(user32.IsWindow(h)&&user32.IsWindowEnabled(h)&&user32.IsWindowVisible(h)){ 10 set.add(i.getValue());
11 } 12 return true; 13 } 14 }, null); 15 return set;//獲得到的窗口PID集合 16 } 17 }

(2)獲取進程圖片

 1 public class Maintest {
 2 
 3     public interface ProcessPathKernel32 extends Kernel32 {
 4         class MODULEENTRY32 extends Structure {
 5             public static class ByReference extends MODULEENTRY32 implements Structure.ByReference {
 6                 public ByReference() {}
 7                 public ByReference(Pointer memory) {
 8                     super(memory);
 9                 }
10             }
11             public MODULEENTRY32() {
12                 dwSize = new WinDef.DWORD(size());
13             }
14 
15             public MODULEENTRY32(Pointer memory) {
16                 super(memory);
17                 read();
18             }
19 
20             public DWORD dwSize;
21             public DWORD th32ModuleID;
22             public DWORD th32ProcessID;
23             public DWORD GlblcntUsage;
24             public DWORD ProccntUsage;
25             public Pointer modBaseAddr;
26             public DWORD modBaseSize;
27             public HMODULE hModule;
28             public char[] szModule = new char[255+1]; // MAX_MODULE_NAME32
29             public char[] szExePath = new char[MAX_PATH];
30             public String szModule() { return Native.toString(this.szModule); }
31             public String szExePath() { return Native.toString(this.szExePath); }
32             @Override
33             protected List<String> getFieldOrder() {
34                 return Arrays.asList(new String[] {
35                         "dwSize", "th32ModuleID", "th32ProcessID", "GlblcntUsage", "ProccntUsage", "modBaseAddr", "modBaseSize", "hModule", "szModule", "szExePath"
36                 });
37             }
38         }
39 
40         ProcessPathKernel32 INSTANCE = (ProcessPathKernel32)Native.loadLibrary(ProcessPathKernel32.class, W32APIOptions.UNICODE_OPTIONS);
41         boolean Module32First(HANDLE hSnapshot, MODULEENTRY32.ByReference lpme);
42         boolean Module32Next(HANDLE hSnapshot, MODULEENTRY32.ByReference lpme);
43     }
44 
45     public static void main(String[] args) throws IOException {
46 
47         HICON[] a=new WinDef.HICON[12];
48         HICON[] b=new WinDef.HICON[11];
49         Set<Integer> Pids=EnumWindow.getTaskPID();//獲取窗口進程的PID
50         int c=1;
51         Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.DEFAULT_OPTIONS);
52         Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();
53         WinNT.HANDLE processSnapshot = 
54                 kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
55         try {
56             while (kernel32.Process32Next(processSnapshot, processEntry)) {
57                 //processEntry.th32ProcessID  程序的PID
58                 //Native.toString(processEntry.szExeFile) 程序的名字(xx.exe)
59                 WinNT.HANDLE moduleSnapshot =kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, processEntry.th32ProcessID);
60                 if(Pids.contains(processEntry.th32ProcessID.intValue())){
61                     String exeName=Native.toString(processEntry.szExeFile).substring(0,Native.toString(processEntry.szExeFile).indexOf(".exe"));
62                     if(exeName.toLowerCase().equals("shellexperiencehost")||exeName.toLowerCase().equals("syntpenh")){//ShellExperienceHost為開始菜單外殼,syntpenh為觸摸板相關程序
63                         continue;
64                     }
65                     try {
66                         ProcessPathKernel32.MODULEENTRY32.ByReference me = new ProcessPathKernel32.MODULEENTRY32.ByReference();
67                         ProcessPathKernel32.INSTANCE.Module32First(moduleSnapshot, me);
68                         //me.szExePath() //程序(xx.exe)所在路徑
69                         Shell32.INSTANCE.ExtractIconEx(me.szExePath(), 0, a, b, c);
70                         if(a.length>0&&Native.toString(processEntry.szExeFile)!=null&&Native.toString(processEntry.szExeFile).length()>0&&Native.toString(processEntry.szExeFile).indexOf(".exe")>=0){//判斷是否有圖標
71                             String fileName=Native.toString(processEntry.szExeFile).substring(0,Native.toString(processEntry.szExeFile).indexOf(".exe"))+".jpg";
72                             if (me.szExePath()!=null&&me.szExePath()!="") {
73                                 File file=new File(me.szExePath());//.exe文件
74                                 File imgFile=new File("C:\\windowTaskBarIcon\\"+fileName);
75                                 if (!imgFile.exists()) {
76                                     imgFile.mkdirs();
77                                 }
78                                 Image image=((ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file)).getImage();
79                                 ImageIO.write((RenderedImage) image,"jpg", imgFile);
80                             }
81                         }
82                     }
83                     finally {
84                         kernel32.CloseHandle(moduleSnapshot);
85                     }
86                 }
87             }
88         }
89         finally {
90             kernel32.CloseHandle(processSnapshot);
91         }
92     }
93 
94 }

5.效果圖

會把獲得的圖片保存到指定的文件夾下面。

技術分享

6.工程完整代碼放在github上

地址:https://github.com/xujinghuan/getWindowTaskIcon

獲取 window任務欄已經打開應用程序窗口(也就是任務管理器中前臺進程)的圖標