Option Explicit
Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
Const MAX_PATH As Integer = 260
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 * MAX_PATH
End Type
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long)
Public Function ListProc() As String    Dim lngReturn As Long
    Dim hSnapShot As Long
    Dim uProcess As PROCESSENTRY32
          
    'Takes a snapshot of the processes and the heaps, modules, and threads used by the processes
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)
    'set the length of our ProcessEntry-type
    uProcess.dwSize = Len(uProcess)
    'Retrieve information about the first process encountered in our system snapshot
    lngReturn = Process32First(hSnapShot, uProcess)
    'set graphics mode to persistent
    Do While lngReturn
        
        Debug.Print Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0))
        
        ListProc = ListProc & Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0)) & vbCrLf
    
        'Retrieve information about the next process recorded in our system snapshot
        lngReturn = Process32Next(hSnapShot, uProcess)
    Loop
    
   
    'close our snapshot handle
    CloseHandle hSnapShot                
End FunctionPrivate Sub Form_Load()MsgBox ListProc()EndEnd Sub以上是一个获得所有进程程序名的程序代码。
问题一:当有中文文件名的程序运行时,得到的中文文件名称是乱码,如何解决?
问题二:MSDN中说szExeFile包含路径和文件名,可我为什么只能得到文件名?如何得到程序路径?
问题三:最上面三个api函数都不能在winnt系统下运行,在winnt系统下如何实现类似功能?

解决方案 »

  1.   

    'This program need a ListBox, a Button and a Label.
    'Add the following to Form1
    Option ExplicitPrivate 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 CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
    Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    Private Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
    Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, _
                                                                ByVal ModuleName As String, ByVal nSize As Long) As Long
    Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, _
                                                                ByVal cb As Long, ByRef cbNeeded As Long) As Long
    Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
    Private Declare Function GetVersionExA Lib "kernel32" (lpVersionInformation As OSVERSIONINFO) As Integer
    Private Type PROCESSENTRY32
          dwSize  As Long
          cntUsage  As Long
          th32ProcessID  As Long                       '  This  process
          th32DefaultHeapID  As Long
          th32ModuleID  As Long                         '  Associated  exe
          cntThreads  As Long
          th32ParentProcessID  As Long           '  This  process's  parent  process
          pcPriClassBase  As Long                     '  Base  priority  of  process  threads
          dwFlags  As Long
          szExeFile  As String * 260                 '  MAX_PATH
    End Type
    Private Type OSVERSIONINFO
          dwOSVersionInfoSize  As Long
          dwMajorVersion  As Long
          dwMinorVersion  As Long
          dwBuildNumber  As Long
          dwPlatformId  As Long                     '1  =  Windows  95.
                                                                        '2  =  Windows  NT
          szCSDVersion  As String * 128
     End Type
     Private Const PROCESS_QUERY_INFORMATION = 1024
     Private Const PROCESS_VM_READ = 16
     Private Const MAX_PATH = 260
     Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
     Private Const SYNCHRONIZE = &H100000
     'STANDARD_RIGHTS_REQUIRED  Or  SYNCHRONIZE  Or  &HFFF
     Private Const PROCESS_ALL_ACCESS = &H1F0FFF
     Private Const TH32CS_SNAPPROCESS = &H2&
     Private Const hNull = 0
     
     Private Function StrZToStr(s As String) As String
           StrZToStr = Left$(s, Len(s) - 1)
     End Function
     
     Private Function getVersion() As Long
           Dim osinfo   As OSVERSIONINFO
           Dim retvalue   As Integer
           osinfo.dwOSVersionInfoSize = 148
           osinfo.szCSDVersion = Space$(128)
           retvalue = GetVersionExA(osinfo)
           getVersion = osinfo.dwPlatformId
     End FunctionPrivate Sub Command1_Click()
        List1.Clear
        Select Case getVersion()
         
        Case 1   'Windows  95/98
         
             Dim f   As Long, sname    As String
             Dim hSnap   As Long, proc    As PROCESSENTRY32
             hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
             If hSnap = hNull Then Exit Sub
             proc.dwSize = Len(proc)
             '  Iterate  through  the  processes
             f = Process32First(hSnap, proc)
             Do While f
                 sname = StrZToStr(proc.szExeFile)
                 List1.AddItem sname
                 f = Process32Next(hSnap, proc)
             Loop
                
             'count
             Label1.Caption = List1.ListCount
        Case 2   'Windows  NT
         
             Dim cb   As Long
             Dim cbNeeded   As Long
             Dim NumElements   As Long
             Dim ProcessIDs()   As Long
             Dim cbNeeded2   As Long
             Dim NumElements2   As Long
             Dim Modules(1 To 200)     As Long
             Dim lRet   As Long
             Dim ModuleName   As String
             Dim nSize   As Long
             Dim hProcess   As Long
             Dim i   As Long
             'Get  the  array  containing  the  process  id's  for  each  process  object
             cb = 8
             cbNeeded = 96
             Do While cb <= cbNeeded
                   cb = cb * 2
                   ReDim ProcessIDs(cb / 4) As Long
                   lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
             Loop
             NumElements = cbNeeded / 4
         
             For i = 1 To NumElements
                   'Get  a  handle  to  the  Process
                   hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
                         Or PROCESS_VM_READ, 0, ProcessIDs(i))
                   'Got  a  Process  handle
                   If hProcess <> 0 Then
                           'Get  an  array  of  the  module  handles  for  the  specified
                           'process
                           lRet = EnumProcessModules(hProcess, Modules(1), 200, _
                                                                                     cbNeeded2)
                           'If  the  Module  Array  is  retrieved,  Get  the  ModuleFileName
                           If lRet <> 0 Then
                                 ModuleName = Space(MAX_PATH)
                                 nSize = 500
                                 lRet = GetModuleFileNameExA(hProcess, Modules(1), _
                                                                 ModuleName, nSize)
                                 List1.AddItem Left(ModuleName, lRet)
                           End If
                   End If
               'Close  the  handle  to  the  process
             lRet = CloseHandle(hProcess)
             Next
             'count
             Label1.Caption = List1.ListCount
        End Select
    End Sub
      

  2.   

    漏了一点:
    在这句
    lngReturn = Process32Next(hSnapShot, uProcess)
    前面加上一句
    uProcess.szExeFile = String$(MAX_PATH, Chr(0))
    比较好
      

  3.   

    to:leolan(史留香)
    在98下问题一和问题二存在吗?如果存在怎么解决?
    还有问题三如何解决?
      

  4.   

    to:baoaya(点头)
    兄弟看清楚问题
      

  5.   

    sorry,没仔细看。
    在nt和2000上是没问题了。
    不知道98是不是满足前两个条件,等我验证了把结果公布。