现在的位置: 首页 > 综合 > 正文

列举系统进程及调用模块

2013年10月10日 ⁄ 综合 ⁄ 共 15572字 ⁄ 字号 评论关闭

好久没有写东西了,这两天晚上抽空又熟悉了一下 TlHelp32 中几个 api 函数,有点收获,也要感谢 yrt888,如果没有他提出这个问题,我也不会研究这几个 api 的用法。下面是这个工具的 prg 版本(不知道如何上传文件到这个博客,换成 prg 版本可是花了点时间的),由于主要是研究 api 函数的用法,所以没有去实现一个工具应有的一些功能,例如点题头排序,右键菜单,自动刷新等,其实要自动刷新很容易,加个计时器,定时调用刷新按钮的 click 即可。

用法:也没什么用法的问题啦,直接运行即可看到结果,隐藏没有提示的操作只有双击 grid 字符列时会弹出模块窗口,双击数值列则弹出线程窗口。 

*!* =============================================================================
*!* 主程序
*!* 作者: dkfdtf
*!* 目的: 熟悉 TlHelp32 中提供的列举系统进程/模块/线程 api 的使用
*!* 历史: 2008.07.03 - 第一版
*!*     2008.07.04 - 第二版, 增加进程树表单视图
*!*     2008.07.05 - 第三版, 可以查看系统进程(如 winlogon.exe)的模块了
*!*     2008.07.06 - 第四版, 应 yrt888 要求加了存储器使用情况显示,更正一个 bug
*!* =============================================================================
IF ( VERSION(5) < 700 )
  MESSAGEBOX( '需要 vfp7 以上版本', 16, '错误' )
  RETURN
ENDIF
IF ( INT(VAL(OS(3))) < 5 )
  MESSAGEBOX( '仅适用于 Win2000 以上操作系统', 16, '错误' )
  RETURN
ENDIF

CLEAR ALL
CLOSE DATABASES
SET TALK OFF
SET SAFETY OFF

m.goProcMgr = NEWOBJECT( 'ProcMgr' )
IF m.goProcMgr.GetProcess()
  m.oFrmProcess = NEWOBJECT( 'frmProcess' )
  m.oFrmProcess.Show
  READ EVENTS
ENDIF

CLOSE DATABASES
RETURN

*!* ================================================================
*!* 类定义
*!* ================================================================
DEFINE CLASS MyGrid AS Grid
  AllowCellSelection = .F.
  DeleteMark = .F.
  RecordMark = .F.
  SplitBar = .F.
  GridLines = 0
  HeaderHeight = 22

  PROCEDURE Init
    This.SetAll( 'Alignment', 2, 'Header' )
    This.SetAll( 'FontName', 'Tahoma' )
    This.SetAll( 'FontSize', 8, 'Column' )
    This.SetAll( 'DynamicBackColor', ;
      'iif(recn()%2==0,rgb(240,250,255),rgb(255,255,255))' )
  ENDPROC
ENDDEFINE

*!* ----------------------------------------------------------------
*!* 进程浏览表单(主表单)
*!* ----------------------------------------------------------------
DEFINE CLASS frmProcess AS Form
  Height = 265
  Width = 370
  ShowWindow = 2
  DoCreate = .T.
  Caption = '系统进程信息查看器'
  AllowOutput = .F.
  Name = 'frmProcess'

  ADD OBJECT grd AS MyGrid WITH ;
    Name = 'grd'

  ADD OBJECT cmdModules AS commandbutton WITH ;
    Top = 228, ;
    Left = 12, ;
    Height = 27, ;
    Width = 72, ;
    Anchor = 6, ;
    Caption = '显示模块', ;
    Name = 'cmdModules'

  ADD OBJECT cmdThreads AS commandbutton WITH ;
    Top = 228, ;
    Left = 91, ;
    Height = 27, ;
    Width = 72, ;
    Anchor = 6, ;
    Caption = '显示线程', ;
    Name = 'cmdThreads'

  ADD OBJECT cmdProcTreeview AS commandbutton WITH ;
    Top = 228, ;
    Left = 170, ;
    Height = 27, ;
    Width = 72, ;
    Anchor = 6, ;
    Caption = '进程树', ;
    Name = 'cmdProcTreeview'

  ADD OBJECT cmdRefresh AS commandbutton WITH ;
    Top = 228, ;
    Left = 312, ;
    Height = 27, ;
    Width = 48, ;
    Anchor = 12, ;
    Caption = '刷新', ;
    Name = 'cmdRefresh'
  
  PROCEDURE Init
    This.Move( ;
      INT( SYSMETRIC(1)*0.2 ), ;
      INT( SYSMETRIC(2)*0.2 ), ;
      INT( SYSMETRIC(1)*0.6 ), ;
      INT( SYSMETRIC(2)*0.6 ) )

    WITH This.grd
      .RecordSource = 'listprocs'

      .ColumnCount = 6
      WITH .Column1
        .ControlSource   = '[ ]+listprocs.imgname'
        .Header1.Caption = '映像名'
        .Width = 100
        .Alignment = 0
      ENDWITH
      WITH .Column2
        .ControlSource   = 'listprocs.pid'
        .Header1.Caption = 'PID'
        .Width = 50
        .Alignment = 2
      ENDWITH
      WITH .Column3
        .ControlSource   = 'listprocs.threads'
        .Header1.Caption = '线程数'
        .Width = 45
        .Alignment = 2
      ENDWITH
      WITH .Column4
        .ControlSource   = 'listprocs.worksize'
        .Header1.Caption = '物理内存'
        .Width = 60
        .Format = 'T'
        .Alignment = 1
      ENDWITH
      WITH .Column5
        .ControlSource   = 'listprocs.pagesize'
        .Header1.Caption = '虚拟内存'
        .Width = 60
        .Format = 'T'
        .Alignment = 1
      ENDWITH
      WITH .Column6
        .ControlSource   = 'listprocs.exefile'
        .Header1.Caption = '映像路径'
        .Width = 1000
        .Alignment = 0
      ENDWITH

      .Init()
      This.SetAll( 'DynamicBackColor', ;
        'iif(recn()%2==0,rgb(255,250,240),rgb(255,255,255))' )

      .Move( 0, 0, This.Width, ;
        This.Height - This.cmdRefresh.Height - 20 )
      .Anchor = 15
    ENDWITH

    GOTO TOP IN listprocs
  ENDPROC

  PROCEDURE Unload
    CLEAR EVENTS
  ENDPROC
  
  PROCEDURE grd.DblClick
    IF ( 'C' == VARTYPE( This.Value ))
      Thisform.cmdModules.Click()
    ELSE
      Thisform.cmdThreads.Click()
    ENDIF
  ENDPROC

  PROCEDURE cmdModules.Click
    IF m.goProcMgr.GetModules( listprocs.pid, listprocs.imgname )
      m.oFrmModules = NEWOBJECT( 'frmModules' )
      WITH m.oFrmModules
        .Caption = ALLTRIM( listprocs.imgname ) ;
          + '(PID=' + TRANSFORM( listprocs.pid ) + ') ' + .Caption
        .Move( Thisform.Left, Thisform.Top )
        .Show(1)
      ENDWITH
    ENDIF
  ENDPROC

  PROCEDURE cmdThreads.Click
    IF m.goProcMgr.GetThreads( listprocs.pid )
      m.oFrmThreads = NEWOBJECT( 'frmThreads' )
      WITH m.oFrmThreads
        .Caption = ALLTRIM( listprocs.imgname ) + ' ' + .Caption
        .Move( Thisform.Left, Thisform.Top )
        .Show(1)
      ENDWITH
    ENDIF
  ENDPROC

  PROCEDURE cmdProcTreeview.Click
    m.oFrmProcTvw = NEWOBJECT( 'frmProcTreeView' )
    WITH m.oFrmProcTvw
      .Move( Thisform.Left, Thisform.Top )
      .Show(1)
    ENDWITH
  ENDPROC

  PROCEDURE cmdRefresh.Click
    LOCAL iOldRec

    m.iOldRec = RECNO( 'listprocs' )
    m.goProcMgr.GetProcess()
    
    TRY
      GOTO ( m.iOldRec ) IN listprocs
    CATCH
      GOTO TOP IN listprocs
    ENDTRY
    Thisform.grd.Refresh()
  ENDPROC
ENDDEFINE

*!* ----------------------------------------------------------------
*!* 模块浏览表单
*!* ----------------------------------------------------------------
DEFINE CLASS frmModules AS form
  Height = 287
  Width = 552
  Desktop = .T.
  ShowWindow = 1
  DoCreate = .T.
  Caption = '模块'
  Name = 'frmModules'

  PROCEDURE Init
    This.NewObject( 'grd', 'MyGrid' )

    WITH This.grd
      .Move( 0, 0, This.Width, This.Height )
      .Anchor = 15

      .RecordSourceType = 1
      .RecordSource = 'listmods'
      .ColumnCount = 4

      WITH .Column1
        .ControlSource = '[ ]+listmods.imgname'
        .Header1.Caption = '映像名'
        .Alignment = 0
        .Width = 100
      ENDWITH
      WITH .Column2
        .ControlSource = 'ltrim(ltrim(trans(listmods.addr,[@0]),[0x]),[0])'
        .Header1.Caption = '加载基址'
        .Alignment = 1
        .Width = 80
      ENDWITH
      WITH .Column3
        .ControlSource = 'listmods.size'
        .Header1.Caption = '大小'
        .Alignment = 1
        .Width = 80
      ENDWITH
      WITH .Column4
        .ControlSource = '[ ]+listmods.exefile'
        .Header1.Caption = '映像路径'
        .Width = 1000
      ENDWITH

      .Init()
      .Visible = .T.
    ENDWITH

    GOTO TOP IN listmods
  ENDPROC
ENDDEFINE

*!* ----------------------------------------------------------------
*!* 线程浏览表单
*!* ----------------------------------------------------------------
DEFINE CLASS frmThreads AS form
  Height = 250
  Width = 216
  Desktop = .T.
  ShowWindow = 1
  DoCreate = .T.
  BorderStyle = 1
  Caption = '线程'
  MaxButton = .F.
  MinButton = .F.
  Name = 'frmThreads'

  PROCEDURE Init
    This.NewObject( 'grd', 'MyGrid' )

    WITH This.grd
      .Move( 0, 0, This.Width, This.Height )
      .Anchor = 15

      .RecordSourceType = 1
      .RecordSource = 'listtrds'
      .ColumnCount = 2

      WITH .Column1
        .ControlSource = 'listtrds.tid'
        .Header1.Caption = '线程 ID'
        .Alignment = 2
        .Width = 70
      ENDWITH
      WITH .Column2
        .ControlSource = 'listtrds.priority'
        .Header1.Caption = '优先级'
        .Alignment = 2
        .Width = 122
      ENDWITH

      .Init()
      .Visible = .T.
    ENDWITH
    
    GOTO TOP IN listtrds
  ENDPROC
ENDDEFINE

*!* ----------------------------------------------------------------
*!* 进程树浏览表单
*!* ----------------------------------------------------------------
DEFINE CLASS frmProcTreeview AS Form
  Height = 382
  Width = 354
  Desktop = .T.
  ShowWindow = 1
  DoCreate = .T.
  Caption = '当前进程树'
  AllowOutput = .F.
  Name = 'frmProcTreeview'

  PROCEDURE Init
    LOCAL cCurKey, oNode

    This.AddObject( 'tvw', 'OleControl', 'COMCTL.TreeCtrl.1' )
    This.AddNodes()

    m.cCurKey = 'p_' +  TRANSFORM( listprocs.pid )
    WITH This.tvw AS COMCTL.TreeCtrl
      .Move( 1, 1, This.Width-2, This.Height-2 )
      WITH .Font
        .Name = 'Tahoma'
        .Size = 9
      ENDWITH
      .Appearance = 0
      .Indentation = 15
      .LineStyle = 1
      .Style = 7

      FOR EACH m.oNode IN .Nodes
        IF ( m.oNode.Key == m.cCurKey )
          m.oNode.EnsureVisible()
          m.oNode.Selected = .T.
        ENDIF
      ENDFOR

      .Anchor = 15
      .Visible = .T.
    ENDWITH
  ENDPROC
  
  HIDDEN PROCEDURE AddNodes
    LOCAL iOldArea, cNodeKey, oNode
    m.iOldArea = SELECT(0)

    SELECT pid, parent, imgname FROM listprocs ;
      WHERE ( 0 == parent ) ;
       OR ( parent NOT IN ( SELECT pid FROM listprocs )) ;
      INTO CURSOR curParent NOFILTER
    SELECT pid, parent, imgname FROM listprocs ;
      WHERE pid NOT IN ( SELECT pid FROM curParent ) ;
      INTO CURSOR curSubProc

    SELECT curParent
    SCAN ALL
      m.cNodeKey = 'p_' + TRANSFORM(pid)
      m.oNode = This.tvw.Nodes.Add( , 1, m.cNodeKey, ;
        ALLTRIM( imgname ) + ' (' +TRANSFORM(pid)+')' )
      This.AddSubNodes( pid, m.cNodeKey )
      m.oNode.Expanded = .T.
    ENDSCAN

    USE IN ( SELECT( 'curParent' ))
    USE IN ( SELECT( 'curSubProc' ))
    SELECT ( m.iOldArea )
  ENDPROC

  HIDDEN PROCEDURE AddSubNodes
    LPARAMETERS tiParentId, tcParentKey

    LOCAL cNodeKey, iOldRec, oNode

    SELECT curSubProc
    m.iOldRec = RECNO()
    SCAN ALL FOR ( parent == m.tiParentId )
      m.cNodeKey = 'p_' + TRANSFORM(pid)
      m.oNode = This.tvw.Nodes.Add( m.tcParentKey, 4, m.cNodeKey, ;
        ALLTRIM( imgname ) + ' (' +TRANSFORM(pid)+')' )
      This.AddSubNodes( pid, m.cNodeKey )
      m.oNode.Expanded = .T.
    ENDSCAN

    GOTO ( m.iOldRec ) IN curSubProc
  ENDPROC
ENDDEFINE


*!* ----------------------------------------------------------------
*!* 进程管理类
*!* ----------------------------------------------------------------
DEFINE CLASS ProcMgr AS Custom
  Name = 'ProcMgr'

  PROCEDURE Init
    DECLARE Long GetLastError IN WIN32API
    DECLARE Long FormatMessage IN WIN32API ;
      Long dwFlags, Long lpSource, Long dwMessageId, Long dwLanguageId, ;
      String @ lpBuffer, Long nSize, Long Arguments
    DECLARE Long CloseHandle IN WIN32API Long hObject

    DECLARE Long GetCurrentProcess IN WIN32API
    DECLARE Long OpenProcess IN WIN32API ;
      Long dwDesiredAccess, Long bInheritHandle, Long dwProcessId
    DECLARE Long OpenThread IN WIN32API ;
      Long dwDesiredAccess, Long bInheritHandle, Long dwThreadId
    DECLARE Long GetThreadPriority IN WIN32API Long hThread
    DECLARE Long OpenProcessToken IN WIN32API ;
      Long ProcessHandle, Long DesiredAccess, Long @ TokenHandle
    DECLARE Long LookupPrivilegeValue IN WIN32API ;
      String pSystemName, String lpName, String @ lpLuid
    DECLARE Long AdjustTokenPrivileges IN WIN32API ;
      Long TokenHandle, Long DisableAllPrivileges, ;
      String @ NewState, Long BufferLength, ;
      String @ PreviousState, Long @ ReturnLength

    DECLARE Long CreateToolhelp32Snapshot IN WIN32API ;
      Long dwFlags, Long th32ProcessID
    DECLARE Long Process32First IN WIN32API Long hSnapshot, String @ lppe
    DECLARE Long Process32Next  IN WIN32API Long hSnapshot, String @ lppe
    DECLARE Long Module32First  IN WIN32API Long hSnapshot, String @ lpme
    DECLARE Long Module32Next   IN WIN32API Long hSnapshot, String @ lpme
    DECLARE Long Thread32First  IN WIN32API Long hSnapshot, String @ lpte
    DECLARE Long Thread32Next   IN WIN32API Long hSnapshot, String @ lpte

    DECLARE Long EnumProcessModules IN PsApi ;
      Long hProcess, String @lphModule, Long cb, Long @ lpcbNeeded
    DECLARE Long GetModuleFileNameEx IN PsApi ;
      Long hProcess, Long hModule, String @ lpExename, Long dwSize
    DECLARE Long GetProcessMemoryInfo IN PsApi ;
      Long hProcess, String @ ppsmemCounters, Long cb

    This.SetPrivileges()
  ENDPROC

  HIDDEN PROCEDURE GetImgFile
    LPARAMETERS tiPid, thModule

    #define PROCESS_VM_READ             0x0010
    #define PROCESS_QUERY_INFORMATION   0x0400
    #define PROCESS_ALL_ACCESS          0x001FFFFF

    IF ( 0 == m.tiPid )
      RETURN ''
    ENDIF

    LOCAL hProc, cFile, iSize

    m.hProc = OpenProcess( ;
      PROCESS_VM_READ + PROCESS_QUERY_INFORMATION, 0, m.tiPid )
    IF ( 0 == m.hProc )
      m.cFile = This.Win32Message( GetLastError())
    ELSE
      m.iSize = 260
      m.cFile = REPLICATE( CHR(0), m.iSize )
      m.iSize = GetModuleFileNameEx( m.hProc, m.thModule, @ m.cFile, m.iSize )
      CloseHandle( m.hProc )
      m.cFile = LEFTC( m.cFile, m.iSize )
    ENDIF
    RETURN This.TransFileName( m.cFile )
  ENDPROC

  HIDDEN PROCEDURE AsciiZString
    LPARAMETERS tcString
    
    RETURN LEFT( m.tcString, AT( CHR(0), m.tcString )-1 )
  ENDPROC

  HIDDEN PROCEDURE Win32Message
    LPARAMETERS tiErrNo

    #define FORMAT_MESSAGE_FROM_SYSTEM    0x1000
    #define FORMAT_MESSAGE_IGNORE_INSERTS 0x0200
    #define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
    #define LANG_USER_DEFAULT             0x0804

    LOCAL cBuffer, iLen

    m.cBuffer = REPLICATE( CHR(0), 256+1 )
    m.iLen = FormatMessage( ;
        FORMAT_MESSAGE_FROM_SYSTEM ;
      + FORMAT_MESSAGE_MAX_WIDTH_MASK ;
      + FORMAT_MESSAGE_IGNORE_INSERTS, ;
      0, m.tiErrNo, LANG_USER_DEFAULT, @ m.cBuffer, 256, 0 )

    RETURN LEFT( m.cBuffer, m.iLen )
  ENDPROC
  
  HIDDEN PROCEDURE GetProcMemInfo
    LPARAMETERS tiPid, tcWorkSize, tcPageSize
    
    #define PROCESS_VM_READ             0x0010
    #define PROCESS_QUERY_INFORMATION   0x0400
    
    LOCAL hProc, cBuff
    
    m.hProc = OpenProcess( ;
      PROCESS_VM_READ + PROCESS_QUERY_INFORMATION, 0, m.tiPid )
    IF ( 0 == m.hProc )
      STORE '??? K' TO m.tcWorkSize, m.tcPageSize
*!*	      This.ErrMsgBox( '获取存储器信息失败!' )
    ELSE
      m.cBuff = BINTOC( 44, 'rs' ) + REPLICATE( CHR(0), 40 )
      IF ( 0 == GetProcessMemoryInfo( m.hProc, @ m.cbuff, LEN( m.cBuff )))
        STORE '??? K' TO m.tcWorkSize, m.tcPageSize
      ELSE
        m.tcWorkSize = This.ToKbMemory( SUBSTR( m.cbuff, 13, 4 ))
        m.tcPageSize = This.ToKbMemory( SUBSTR( m.cbuff, 33, 4 ))
      ENDIF
      CloseHandle( m.hProc )
    ENDIF
  ENDPROC
  
  HIDDEN PROCEDURE ToKbMemory
    LPARAMETERS tcSize
    LOCAL cKilo
    
    m.cKilo = TRANSFORM( CTOBIN( m.tcSize, 'rs' ) / 1024 )
    RETURN IIF( '.' $ m.cKilo, RTRIM( m.cKilo, '0' ), m.cKilo ) + ' K'
  ENDPROC
  
  PROCEDURE GetProcess
    #define TH32CS_SNAPPROCESS      0x00000002
    #define ERROR_NO_MORE_FILES     18

    LOCAL hSS, iSize, cBuff, iPid, tcMem1, tcMem2

    m.hSS = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 )
    IF ( -1 == m.hSS )
      This.ErrMsgBox( '创建进程快照失败!' )
      RETURN .F.
    ENDIF

    m.iSize = 8*4+260
    m.cBuff = BINTOC( 4+m.iSize, 'rs' ) + REPLICATE( CHR(0), m.iSize )
    IF ( 0 == Process32First( m.hSS, @ m.cBuff ))
      CloseHandle( m.hSS )
      This.ErrMsgBox( '获取进程信息失败!' )
      RETURN .F.
    ENDIF

    IF USED( 'listprocs' )
      ZAP IN listprocs
    ELSE
      CREATE CURSOR listprocs ( ;
      pid I, parent I, threads I, imgname C(250), exefile C(250), ;
      	worksize C(12), pagesize C(12) )
    ENDIF

    DO WHILE .T.
      m.iPid = CTOBIN( SUBSTR( m.cBuff, 9, 4 ), 'rs' )
      STORE '' TO m.tcMem1, m.tcMem2
      This.GetProcMemInfo( m.iPid, @ m.tcMem1, @ m.tcMem2 )
      INSERT INTO listprocs ;
        ( pid, parent, threads, imgname, exefile, worksize, pagesize ) ;
      VALUES ( m.iPid, ;
        CTOBIN( SUBSTR( m.cBuff, 25, 4 ), 'rs' ), ;
        CTOBIN( SUBSTR( m.cBuff, 21, 4 ), 'rs' ), ;
        IIF( 0 == m.iPid, '系统空闲进程', ;
          This.AsciiZString( SUBSTR( m.cBuff, 37, 260 ))), ;
        This.GetImgFile( m.iPid, 0 ), ;
        m.tcMem1, m.tcMem2 )
      
      m.cBuff = BINTOC( 4+m.iSize, 'rs' ) + REPLICATE( CHR(0), m.iSize )
      IF ( 0 == Process32Next( m.hSS, @ m.cBuff )) ;
        OR ( ERROR_NO_MORE_FILES == GetLastError())
        EXIT
      ENDIF
    ENDDO
    CloseHandle( m.hSS )
  ENDPROC

  PROCEDURE GetModules
    LPARAMETERS tiPid, tcProcName

    #define TH32CS_SNAPMODULE       0x00000008
    #define ERROR_NO_MORE_FILES     18

    LOCAL hSS, iSize, cBuff, cImgName

    m.tcProcName = LOWER( ALLTRIM( m.tcProcName ))

    m.hSS = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, m.tiPid )
    IF ( -1 == m.hSS )
      This.ErrMsgBox( '创建模块快照失败!' )
      RETURN .F.
    ENDIF

    m.iSize = 8*4+256+260
    m.cBuff = BINTOC( 4+m.iSize, 'rs' ) + REPLICATE( CHR(0), m.iSize )
    IF ( 0 == Module32First( m.hSS, @ m.cBuff ))
      CloseHandle( m.hSS )
      This.ErrMsgBox( '获取模块信息失败!' )
      RETURN .F.
    ENDIF

    IF USED( 'listmods' )
      ZAP IN listmods
    ELSE
      CREATE CURSOR listmods ( ;
        addr I, size I, imgname C(250), exefile C(250) )
    ENDIF

    DO WHILE .T.
      m.cImgName = This.AsciiZString( SUBSTR( m.cBuff, 33, 260 ))
      IF ( LOWER( m.cImgName ) == m.tcProcName )
        m.cImgName = '* ' + m.cImgName
      ENDIF
      
      INSERT INTO listmods ( addr, size, imgname, exefile ) ;
      VALUES ( ;
        CTOBIN( SUBSTR( m.cBuff, 21, 4 ), 'rs' ), ;
        CTOBIN( SUBSTR( m.cBuff, 25, 4 ), 'rs' ), ;
        m.cImgName, ;
        This.TransFileName( This.AsciiZString( SUBSTR( m.cBuff, 289, 260 ))))
      
      m.cBuff = BINTOC( 4+m.iSize, 'rs' ) + REPLICATE( CHR(0), m.iSize )
      IF ( 0 == Module32Next( m.hSS, @ m.cBuff )) ;
        OR ( ERROR_NO_MORE_FILES == GetLastError())
        EXIT
      ENDIF
    ENDDO
    CloseHandle( m.hSS )
  ENDPROC

  PROCEDURE GetThreads
    LPARAMETERS tiPid

    #define TH32CS_SNAPTHREAD       0x00000004
    #define ERROR_NO_MORE_FILES     18

    LOCAL hSS, iSize, cBuff, Pid, Tid

    m.hSS = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 )
    IF ( -1 == m.hSS )
      This.ErrMsgBox( '创建线程快照失败!' )
      RETURN .F.
    ENDIF

    m.iSize = 6*4
    m.cBuff = BINTOC( 4+m.iSize, 'rs' ) + REPLICATE( CHR(0), m.iSize )
    IF ( 0 == Thread32First( m.hSS, @ m.cBuff ))
      CloseHandle( m.hSS )
      This.ErrMsgBox( '获取线程信息失败!' )
      RETURN .F.
    ENDIF

    IF USED( 'listtrds' )
      ZAP IN listtrds
    ELSE
      CREATE CURSOR listtrds ( tid I, priority C(15) )
    ENDIF

    DO WHILE .T.
      m.Pid = CTOBIN( SUBSTR( m.cBuff, 13, 4 ), 'rs' )
      IF ( m.Pid == m.tiPid )
        m.Tid = CTOBIN( SUBSTR( m.cBuff, 9, 4 ), 'rs' )
        INSERT INTO listtrds ( tid, priority ) ;
          VALUES ( m.Tid, This.GetThreadPri( m.Tid ))
      ENDIF
      
      m.cBuff = BINTOC( 4+m.iSize, 'rs' ) + REPLICATE( CHR(0), m.iSize )
      IF ( 0 == Thread32Next( m.hSS, @ m.cBuff )) ;
        OR ( ERROR_NO_MORE_FILES == GetLastError())
        EXIT
      ENDIF
    ENDDO
    CloseHandle( m.hSS )
  ENDPROC

  HIDDEN PROCEDURE SetPrivileges
    #define PROCESS_QUERY_INFORMATION   0x0400
    #define TOKEN_QUERY                 0x0008
    #define TOKEN_ADJUST_PRIVILEGES     0x0020

    #define SE_PRIVILEGE_ENABLED        0x00000002
    #define SE_PRIVILEGE_REMOVED        0X00000004

    LOCAL hToken, cLuid, cState

    m.hToken = 0
    IF ( 0 == OpenProcessToken( GetCurrentProcess(), ;
      TOKEN_QUERY + TOKEN_ADJUST_PRIVILEGES, @ m.hToken ))
      This.ErrMsgBox( '获取进程令牌时发生错误!' )
    ELSE
      m.cLuid = SPACE(8)
      IF ( 0 == LookupPrivilegeValue( NULL, 'SeDebugPrivilege', @ m.cLuid ))
        This.ErrMsgBox( '获取进程权限提升标识时发生错误!' )
      ELSE
        m.cState = BINTOC( 1, 'rs' ) + m.cLuid + BINTOC( SE_PRIVILEGE_ENABLED, 'rs' )
        IF ( 0 == AdjustTokenPrivileges( ;
          m.hToken, 0, @ m.cState, 0, NULL, 0 ))
          This.ErrMsgBox( '提升进程权限时发生错误!' )
        ENDIF
      ENDIF
      CloseHandle( m.hToken )
    ENDIF
  ENDPROC

  HIDDEN PROCEDURE GetThreadPri
    LPARAMETERS tid

    #define THREAD_ALL_ACCESS      0x001F03FFF

    LOCAL hId, iPri, cPri

    m.hId = OpenThread( THREAD_ALL_ACCESS, 0, m.tid )
    IF ( 0 == m.hId )
      This.ErrMsgBox( '获取线程优先级失败!' )
      RETURN '未知'
    ELSE
      m.iPri = GetThreadPriority( m.hId )
      DO CASE
      CASE ( 0 == m.iPri )
        m.cPri = '正常'
      CASE ( 15 == m.iPri )
        m.cPri = '实时'
      CASE ( -15 == m.iPri )
        m.cPri = '空闲'
      CASE ( m.iPri < 0 )
        m.cPri = '低于正常'
      OTHERWISE
        m.cPri = '高于正常'
      ENDCASE
      CloseHandle( m.hId )
      RETURN '(' + TRANSFORM(m.iPri) + ')' + m.cPri
    ENDIF
  ENDPROC

  HIDDEN PROCEDURE ErrMsgBox
    LPARAMETERS tcTitle

    Messagebox( m.tcTitle + 0h0d0a0d0a ;
    + '错误信息: ' + This.Win32Message( GetLastError ()), ;
    16, '错误' )
  ENDPROC

  HIDDEN PROCEDURE TransFilename
    LPARAMETERS tcFileName

    LOCAL cDummy, cTrueName

    IF ( LEN( m.tcFileName ) > 2 ) AND !( ':' == SUBSTR( m.tcFileName, 2, 1 ))
      m.tcFileName = LTRIM( m.tcFileName, '/??/' )
      IF ( '/' == LEFT( m.tcFileName, 1 ))
        m.cDummy = STREXTRACT( m.tcFileName, '/', '/', 1, 6 )
        m.cTrueName = ADDBS( GETENV( ALLTRIM( m.cDummy, '/' )))
        IF !EMPTY( m.cTrueName )
          m.tcFileName = STRTRAN( m.tcFileName, m.cDummy, m.cTrueName )
        ENDIF
      ENDIF
    ENDIF

    RETURN m.tcFileName
  ENDPROC
ENDDEFINE


抱歉!评论已关闭.