获取 window任务栏已经打开应用程序窗口(也就是任务管理器中前台进程)的图标
标签:nta tps sentry xtend extends 效果图 rri slist thread
获取 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 getTaskPID() {
3 User32 user32 = User32.INSTANCE;
4 Set set=new HashSet();
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 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 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任务栏已经打开应用程序窗口(也就是任务管理器中前台进程)的图标
标签:nta tps sentry xtend extends 效果图 rri slist thread
原文地址:http://www.cnblogs.com/xujinghuan/p/7531092.html
评论