| 查看: 1712 | 回复: 2 | |||
| 本帖产生 1 个 程序强帖 ,点击这里进行查看 | |||
Nkxz铁杆木虫 (著名写手)
|
[求助]
获取windows任务管理器任务名
|
||
|
我想获取系统当前进程名称列表,比如当前系统有20个进程,我想把每个进程的名称输 出来,因为学的是matlab,想做这样的事情确实比较难,不知道有没有高手能用其他语 言编一个这样的程序,并且生成dll文件,这样我可以调用。 我在网上找到了很多程序都可以做这样的事情,但是不知道怎么编译,求高手助 阵!!!,如果有人可以做这样的事,或者可以帮忙把下面的程序编译成dll文件,请把 结果发到我的邮箱nkchem09@126.com using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace tasklist { class Program { static void Main(string[] args) { //创建新的 Process 组件的数组 Process[] myProcesses = Process.GetProcesses(); Console.WriteLine("以下获得的为正在运行的进程" ;Console.WriteLine ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" ;foreach (Process myProcess in myProcesses) { Console.WriteLine(myProcess.ProcessName); } int taskcount = myProcesses.Length; Console.WriteLine ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" ;Console.WriteLine("共有进程数:"+taskcount.ToString()); Console.ReadLine(); } } } [ Last edited by Nkxz on 2011-12-7 at 11:20 ] |
» 猜你喜欢
导师想让我从独立一作变成了共一第一
已经有9人回复
博士读完未来一定会好吗
已经有23人回复
到新单位后,换了新的研究方向,没有团队,持续积累2区以上论文,能申请到面上吗
已经有11人回复
读博
已经有4人回复
JMPT 期刊投稿流程
已经有4人回复
心脉受损
已经有5人回复
Springer期刊投稿求助
已经有4人回复
小论文投稿
已经有3人回复
申请2026年博士
已经有6人回复
» 本主题相关价值贴推荐,对您同样有帮助:
大家讨论一下在名校跟不出名的导师读博有意义吗?
已经有21人回复
tyhjqxbz
主管区长 (文坛精英)
- 程序强帖: 1
- 应助: 220 (大学生)
- 贵宾: 31.322
- 金币: 140745
- 散金: 60553
- 红花: 883
- 沙发: 1020
- 帖子: 32994
- 在线: 3441.8小时
- 虫号: 782124
- 注册: 2009-05-29
- 专业: 能源化工
- 管辖: 注册执考区
【答案】应助回帖
★ ★
ben_ladeng(金币+2): 欢迎常来 2011-12-07 22:35:50
Nkxz(金币+10): 谢谢 2011-12-08 08:27:29
余泽成(程序强帖+1): 2011-12-08 14:08:57
ben_ladeng(金币+2): 欢迎常来 2011-12-07 22:35:50
Nkxz(金币+10): 谢谢 2011-12-08 08:27:29
余泽成(程序强帖+1): 2011-12-08 14:08:57
|
下载源代码 在编写工具程序以及系统管理程序的时候。常常需要获取某个进程的主窗口以及创建此进程的程序名。获取主窗口的目的是向窗口发送各种消息。获取启动进程的程序名可以控制对进程的操作。但是有些进程往往有多个主窗口。你要的是哪一个主窗口呢?如果你用过Outlook程序,你就会发现它有多个主窗口,一个窗口列出收件箱和其它文件夹。如果你打开e-mail,便会有另外一个窗口显示信息。它们都是没有父窗口(或者说宿主窗口)的主窗口。运行一下Spy程序,你甚至会发现它们的窗口类名都相同:rctrl_renwnd32。资源管理器(Explorer.exe)也有不止一个主窗口。如图一所示,资源管理器有两个主窗口。一般来讲,想要获取主窗口,凭窗口的式样或类名,你没有什么办法知道哪一个窗口是真正意义上的主窗口。 首先我们讨论如何从多个窗口中获取主窗口?其实很容易。利用两个API函数便可以实现。这两个API是 EnumWindows 和 GetWindowThreadProcessId。如果你对这两个函数不熟悉,不要怕,本文提供了一个C++类来对这两个API进行封装。这个类叫 CMainWindowIterator,用它可以枚举某个进程(已知进程ID)的所有主窗口。这正是我们想要的东西。其使用方法如下: DWORD pid = // 已知某个进程的ID CMainWindowIterator itw(pid); for (HWND hwnd = itw.First(); hwnd; hwnd=itw.Next()) { // do something } 就这么简单,CMainWindowIterator派生于一个更通用的类:CWindowIterator,CWindowIterator负责将::EnumWindows函数打包以隐藏回调细节。它有一个虚拟函数OnWindow,你可以在派生类中重写这个函数,从而可以用任何方式来枚举窗口。CMainWindowIterator就是重写了OnWindow函数,让它只获取属于某个给定进程的主窗口: // (在构造函数中设置m_pid) BOOL CMainWindowIterator::OnWindow(HWND hwnd) { if ((GetWindowLong(hwnd,GWL_STYLE) & WS_VISIBLE)) { DWORD pidwin; GetWindowThreadProcessId(hwnd, &pidwin); if (pidwin==m_pid) return TRUE; } return FALSE; } 这两个类的定义如下:(对应的文件是 EnumProc.h 和 EnumProc.cpp) ////////////////////////////////////////////////////// // 这个类主要是封装::EnumWindows,列举顶层窗口 // class CWindowIterator { protected: HWND* m_hwnds; // 隶属于某个进程PID窗口句柄数组 DWORD m_nAlloc; // 数组大小 DWORD m_count; // 找到的窗口句柄数 DWORD m_current; // 当前的窗口句柄 static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lp); // 虚拟枚举函数 virtual BOOL OnEnumProc(HWND hwnd); // 在派生中改写此函数来过滤不同种类的窗口 virtual BOOL OnWindow(HWND hwnd) { return TRUE; } public: CWindowIterator(DWORD nAlloc=1024); ~CWindowIterator(); DWORD GetCount() { return m_count; } HWND First(); HWND Next() { return m_hwnds && m_current }; //////////////////////////////////// // 列举某个进程的顶层窗口 // class CMainWindowIterator : public CWindowIterator { protected: DWORD m_pid; // 进程ID virtual BOOL OnWindow(HWND hwnd); public: CMainWindowIterator(DWORD pid, DWORD nAlloc=1024); ~CMainWindowIterator(); }; 图一是用上述C++类编写的一个控制台程序lp.exe的输出画面。最后两栏分别是对应进程的“窗口句柄”和“类名/窗口标题”。其命令行开关“/ct”表示列出窗口类名(c)和窗口标题(t)。 图一 一般来讲,如果隶属于某个进程的窗口没有可见的父窗口,那么这个窗口就可以认为是此进程的主窗口。对WS_VISIBLE的检查很重要,因为有些应用创建多个不可见的顶层窗口。关于CMainWindowIterator类的使用细节请参见本文的例子源代码。 接下来我们来讨论如何获取创建进程的程序文件名。有人用各种方法尝试过,比如:GetModuleFileName,GetModuleInstance 和 GetModuleHandle,好像都不行。为什么呢?其实,方法是没错,但调用这些函数得到的只是当前正在运行的这个进程已经加载的模块名(modules),不能用于获取其它进程所加载的模块。因此,必须想别的办法,首先要考虑两种情况,一种是如果你写的程序在Windows NT,Windows 2000,Windows XP环境运行,则可以使用PSAPI,这是一个Windows操作系统中比较新的DLL,利用其中输出的API函数可以获取进程和模块的详细信息。另一种是如果你写的程序在Windows 9x或者Windows Me中运行,则必须借助于ToolHelp,限于本文的篇幅,我在这里不介绍如何使用ToolHelp,如果你感兴趣的话可以参考,MSDN的技术支持文章Q175030,题目为“如何在Win32中枚举应用程序”。 PSAPI中有一个函数是GetModuleFileNameEx。它通过某个进程和模块句柄作为参数来获得模块名。那么对于某个进程来说,你怎么知道哪个模块是启动进程的执行文件呢呢?PSAPI中的另一个函数EnumProcessModules将某个进程中所有模块的模块句柄填充到一个数组中。这个数组的第一个元素便是主模块的句柄,所以你用下面的代码来得到第一个HMODULE: DWORD count; HMODULE hm[1]; EnumProcessModules(hProcess, hm, 1, &count); 然后调用GetModuleFileNameEx。 实际上从前面的图一中可以看到,在lp.exe程序中我们已经实现了罗列进程及其对应的模块名。程序的实现细节中还用到了PSAPI输出的API函数EnumProcesses来枚举所有运行进程,为了对具体的细节进行封装,我如法炮制编写了与CWindowIterator 和CMainWindowIterator类似的两个C++类:CProcessIterator 和 CProcessModuleIterator ,它们分别对EnumProcesses 和EnumProcessModules API函数进行了封装。有了这两个打包类,一切都变得如此简单。 CProcessIterator itp; for (DWORD pid=itp.First(); pid; pid=itp.Next()) { // 处理每一个进程 } 下面是获取创建进程的EXE文件名的方法: CProcessModuleIterator itm(pid); HMODULE hModule = itm.First(); // .EXE TCHAR modname[_MAX_PATH]; GetModuleBaseName(itm.GetProcessHandle(), hModule, modname, _MAX_PATH); 因为lp显示出来的并不是一个含全路径的模块文件名,所以我用另外一个PSAPI函数GetModuleBaseName来代替GetModuleFileNameEx从而获取全路径名。此外,由于CProcessModuleIterator自己会打开进程枚举模块,所以不必调用OpenProcess。用CProcessModuleIterator::GetProcessHandle可以得到已打开进程的句柄。lp程序还用CMainWindowIterator来显示每个特定进程的所有主窗口。下面是CProcessIterator 和 CProcessModuleIterator的定义: //////////////////////////////////////////////////////////////////////////////////////// // 进程列举类 -- 列举出系统中的所有进程,但总是跳过第一个PID=0的进程,即空闲进程(IDLE) // class CProcessIterator { protected: DWORD* m_pids; // 包含进程IDs的数祖 DWORD m_count; // 数组大小 DWORD m_current; // 当前数组项 public: CProcessIterator(); ~CProcessIterator(); DWORD GetCount() { return m_count; } DWORD First(); DWORD Next() { return m_pids && m_current }; ///////////////////////////////////////////////////////////////// // 列举某个进程的模块,第一个模块就是创建此进程的主exe程序 // class CProcessModuleIterator { protected: HANDLE m_hProcess; // 进程句柄 HMODULE* m_hModules; // 模块句柄数组 DWORD m_count; // 数组大小 DWORD m_current; // 当前模块的句柄 public: CProcessModuleIterator(DWORD pid); ~CProcessModuleIterator(); HANDLE GetProcessHandle() { return m_hProcess; } DWORD GetCount() { return m_count; } HMODULE First(); HMODULE Next() { return m_hProcess && m_current < m_count ? m_hModules[m_current++] : 0; } }; |

2楼2011-12-07 22:20:25
tyhjqxbz
主管区长 (文坛精英)
- 程序强帖: 1
- 应助: 220 (大学生)
- 贵宾: 31.322
- 金币: 140745
- 散金: 60553
- 红花: 883
- 沙发: 1020
- 帖子: 32994
- 在线: 3441.8小时
- 虫号: 782124
- 注册: 2009-05-29
- 专业: 能源化工
- 管辖: 注册执考区
【答案】应助回帖
★ ★
jjdg(金币+2): 辛苦了 2011-12-08 00:21:22
Nkxz(金币+10): 谢谢了 2011-12-08 08:28:48
jjdg(金币+2): 辛苦了 2011-12-08 00:21:22
Nkxz(金币+10): 谢谢了 2011-12-08 08:28:48
|
当前运行的程序列表: Option Explicit Private Type PROCESSENTRY32 dwSize As Long cntUsage As Long th32ProcessID As Long th32DefaultHeapID As Long th32ModuleID As Long cntThreads As Long th32ParentProcessID As Long pcPriClassBase As Long dwFlags As Long szExeFile As String * 1024 End Type Private Declare Function Process32First Lib "kernel32 " (ByVal HSnapshot As Long, lppe As PROCESSENTRY32) As Long Private Declare Function Process32Next Lib "kernel32 " (ByVal HSnapshot As Long, lppe As PROCESSENTRY32) As Long Private Declare Function CreateToolhelp32Snapshot Lib "kernel32 " (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long Private Declare Function CloseHandle Lib "kernel32 " (ByVal hObject As Long) As Long Const TH32CS_SNAPPROCESS = &H2 Private Sub Form_Load() Dim Pro As PROCESSENTRY32 Dim HSnapshot As Long List1.Clear HSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) If HSnapshot Then Pro.dwSize = Len(Pro) If (Process32First(HSnapshot, Pro)) Then Do List1.AddItem Pro.szExeFile List1.ItemData(List1.NewIndex) = Pro.th32ProcessID Loop Until (Process32Next(HSnapshot, Pro) < 1) End If CloseHandle (HSnapshot) End If End Sub |

3楼2011-12-07 22:20:39













;
回复此楼