科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Windows任务管理器开发原理与实现

Windows任务管理器开发原理与实现

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Windows2000/XP内含的任务管理器(Taskmgr)相信大家都熟悉吧,相比之下XP里的要比2000功能更加强大。

作者:佚名 来源:BLOG 2007年10月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
说了这么多,我们也该谈谈如何实现了。

  1.窗口信息

  MS为我们提供了打开特定桌面和枚举桌面窗口的函数。

  hDesk=OpenDesktop(lpszDesktop,0,FALSE,DESKTOP_ENUMERATE);
  //打开我们默认的Default桌面;
  EnumDesktopWindows(hDesk,(WNDENUMPROC)EnumWindowProc,0);
  //枚举打开桌面上的所有窗口,由回调函数实现。
  BOOL __stdcall EnumWindowProc(HWND, LPARAM);
  //在回调函数中,我们可以获得窗口的标题和相关进程,线程信息;
  GetWindowText(hWnd,szWindowText,dwMaxCount);
  GetWindowThreadProcessId(hWnd,&dwPID);

  2.设备驱动器信息(服务和设备驱动器差不多,在此不做重复)

  设备驱动信息有服务控制管理器(SCM)来管理的,我要打开服务控制管理器,并枚举所有的设备驱动器。

  OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  //以所有权限打开服务控制管理器;
  EnumServicesStatus(schManager,dwDeviceType,dwDeviceState,
        EnumStatus,dwBufSize,&dwBytesNeeded,
       &dwDevicesReturned,&dwResumeHandle))
  //枚举所有设备的当前状态;
  CloseServiceHandle(schManager);
  //记住,在结束访问后要关闭服务句柄;
  OpenService(schManager,szDeviceName,SERVICE_ALL_ACCESS);
  //打开特定的设备驱动器;
  QueryServiceConfig(schDevice,lpDeviceConfig,
           1024*8,&dwBytesNeeded);
  //查询驱动器的服务配置信息;
  QueryServiceStatus(schDevice,&DeviceStatus);
  //查询设备驱动器的当前状态;
  QueryServiceConfig2(schDevice,SERVICE_CONFIG_DESCRIPTION,
  (LPBYTE)lpDeviceDescription,8*1024,&dwBytesNeeded)
  //查询设备的描述信息;
  StartService(schDevice,0,NULL);
  //启动设备;
  ControlService(schDevice,SERVICE_CONTROL_STOP,&DeviceStatus);
  //停止设备;
  DeleteService(schDevice);
  //删除设备;

  3.磁盘信息

  我们希望获得系统所有磁盘的信息,包括软盘,硬盘,光盘等等;

  GetLogicalDriveStrings(dwBufferLength,lpBuffer);
  //获得逻辑设备的信息;
  GetVolumeInformation(lpRootPathName,lpVolumeNameBuffer,
   dwVolumeNameSize,&dwVolumeSerialNumber,
   &dwMaximumComponentLength,&dwFileSystemFlags,
      lpFileSystemNameBuffer,dwFileSystemNameSize);
  //获得磁盘卷信息,包括卷名称和格式类型;
  GetDiskFreeSpaceEx(lpRootPathName,&FreeBytesAvailable,
         &TotalNumberOfBytes,&TotalNumberOfFreeBytes);
  //探测磁盘的空间使用情况;

  4.环境变量

  我们可以从注册表中获得环境块的信息:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment,当然要使用注册表的函数。

  RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegKey,0,KEY_QUERY_VALUE,&hKey);
  //打开注册表的键;
  RegEnumValue(hKey,dwIndex,EnvironVariable,
         &dwVariableLength,NULL,NULL,NULL,NULL);
  //查询我们需要的信息值;
  GetEnvironmentVariable(EnvironVariable,EnvironString,1024);
  //获得环境变量的字符串信息;

  5.事件记录信息

  OpenEventLog(NULL,szLog);
  //打开时间日志记录;
  GetOldestEventLogRecord(hEvent,&dwThisRecord);
  //获得最新的日志信息,以便继续查找;
  ReadEventLog(hEvent,EVENTLOG_FORWARDS_READ │ EVENTLOG_SEQUENTIAL_READ,
0,pEventLogRecord,1024*32,&dwRead,&dwNeeded)
  //读去日志信息;
  LookupAccountSid(NULL,pSid,szName,&dwName,szDomain,&dwDomain,&SNU);
  //获取账户的SID,以便获得账户的用户名称;
  GetNumberOfEventLogRecords(hEvent,&dwTotal);
  //获得事件日志的总数;
  CloseEventLog(hEvent);
  //不要忘记关闭事件句柄;

  6.网络共享

  我们使用第二等级的网络共享搜索;

  NetShareEnum(NULL,dwLevel,(PBYTE *)&pBuf,MAX_PREFERRED_LENGTH,&entriesread,&totalentries,&resume);
  //列举所有的共享目录及相关信息;
  NetApiBufferFree(pBuf);
  //释放缓冲区;
  NetShareDel(NULL,(char *)lpShareNameW,0);
  //删除网络共享目录;

  7.网络适配器信息

  我们要探测NIC的信息和网络流量;

  GetAdaptersInfo(&AdapterInfo,&OutBufLen);
  //获取适配器信息;

  8.系统性能

  获取系统的存储器使用情况;

  GetPerformanceInfo(&PerfInfo,sizeof(PERFORMACE_INFORMATION))
  //获取系统性能信息;

  9.进程/线程/模块信息

  在此我们使用工具帮助函数(ToolHelp32)和系统

  OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY │ TOKEN_ADJUST_PRIVILEGES,&hToken);
  //打开进程的令牌,提升权限;
  AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
  //将进程的权限提升到支持调试(Debug);
  CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  //创建进程的快照;
  Process32First(hProcessSnap,&ProcessEntry32);
  Process32First(hProcessSnap,&ProcessEntry32);
  //枚举所有进程;
  OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,ProcessEntry32.th32ProcessID);
  //打开特定进程,以查询进程相关信息;
  GetProcessTimes(hProcess,&CreateTime,&ExitTime,&KernelTime,&UserTime);
  //获取进程的时间信息;
  GetProcessMemoryInfo(hProcess,&PMCounter,sizeof(PMCounter));
  //获取进程的存储区信息;
  GetPriorityClass(hProcess);
  //获取进程的优先权;
  GetProcessIoCounters(hProcess,&IoCounters);
  //获取进程的IO使用情况;
  CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
  //创建模块快照;
  Module32First(hModuleSnap, &ModuleEntry32);
  Module32Next(hModuleSnap, &ModuleEntry32);
  //枚举进程模块信息;
  CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  //创建线程快照;
  Thread32First(hThreadSnap, &ThreadEntry32);
  Thread32Next(hThreadSnap, &ThreadEntry32);
  //枚举线程信息;
  OpenThread(THREAD_ALL_ACCESS,FALSE,ThreadEntry32.th32ThreadID);
  //打开线程,须自己获得此函数地址;
  TerminateProcess(hProcess,0);
  //终止进程;
  SuspendThread(hThread);
  //悬挂线程;
  ResumeThread(hThread);
  //激活线程;

  10.关机

  AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
  //调整进程令牌,使其支持关机;
  ExitWindowsEx(EWX_LOGOFF,0);
  //注销系统;
  LockWorkStation();
  //锁定系统;
  InitiateSystemShutdown(NULL,szMessage,dwTimeout,FALSE,bSig);
  //支持到记时和消息显示的关机/重启;
  SetSystemPowerState(bSig,FALSE);
  //系统休眠/冬眠;

  11.用户信息

  NetUserEnum(NULL,dwLevel,FILTER_NORMAL_ACCOUNT,(LPBYTE*)&pBuf,       dwPrefMaxLen,&dwEntriesRead,&dwTotalEntries,&dwResumeHandle);
  //枚举系统用户信息;
  NetUserDel(NULL,lpUserNameW);
  //删除指定用户;

  12.系统版本信息

  GetVersionEx((LPOSVERSIONINFO)&osviex);
  //获取操作系统的版本信息;

  我们也可以通过注册表(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)获取相关信息:

  GetTickCount();
  //获取开机时间;
  GetComputerName(szInfo,&dwInfo);
  //获取计算机名称;
  GetUserName(szInfo,&dwInfo);
  //获取计算机用户名;
  GetWindowsDirectory(szInfo,MAX_PATH+1);
  //获取Windows目录;
  GetSystemDirectory(szInfo,MAX_PATH+1);
  //获取系统目录;

  小结:

  虽然我们现在已经实现了任务管理器的各项功能,甚至比Windows自带的功能还要强大,不过却没有什么兴奋的感觉。因为看看我们的代码,您就会发现那些都是直接调用的Win32API函数,但是我们清楚系统底层究竟是怎么实现的吗?不管我们是否只是为了实现一个功能,还是对操作系统感兴趣,我们都应该更多的对系统底层进行研究,而不仅仅是只会使用高层函数的程序员。虽然微软为我们隐藏了很多的内部细节,但正是这种底层的秘密激发了我们对其进行深入研究的兴趣和动力。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章