獲取 window任務欄已經打開應用程序窗口(也就是任務管理器中前臺進程)的圖標
阿新 • • 發佈:2017-09-16
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(newUser32.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任務欄已經打開應用程序窗口(也就是任務管理器中前臺進程)的圖標