首页 > 解决方案 > 在VB6中按名称获取进程

问题描述

我想通过它的名字找到一个 proses ID 并等待它的完成继续......现在我只是试图通过名字来获取这个 proses,它对我不起作用......

我尝试使用这个例子

https://www.experts-exchange.com/questions/20480608/Get-All-process-exe-names-in-Visual-Basic-6-0.html

但我从 GetProcesses 方法得到 0

例如在 C# 中,我编写了这段代码

class Program
    {
        static void Main(string[] args)
        {
            int x = Process.GetProcessesByName("PulserTester").First().Id;
        }
    }

这段代码工作得很好并返回了 ID 87068 我现在在调试时同时运行了这两个程序,所以我确信 PulserTester 程序正在运行......

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
    ByVal hWnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) 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 TerminateProcess Lib "kernel32" (ByVal hProcess As Long, _
ByVal uExitCode As Long) As Long

Private Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)


Public Function GetProcesses(strProcess As String) As Long

 Dim lProcCount     As Long
 Dim lProcPoss      As Long
 Dim lNum           As Long
 Dim ProcessIDs()   As Long
 Dim cbNeeded2      As Long
 Dim NumElements2   As Long
 Dim arrModules(1 To 200) As Long
 Dim lRet           As Long
 Dim sModName       As String
 Dim hwndProcess    As Long
 Dim iCounter       As Long

 Const SIZE = 500
 Const PROCESS_QUERY_INFORMATION = 1024
 Const PROCESS_VM_READ = 16
 Const PROCESS_ALL_ACCESS = &H1F0FFF

 'need to get the array containing the process id's for each process object

 lProcCount = 8
 lProcPoss = 96
 Do While lProcCount <= lProcPoss
     lProcCount = lProcCount * 2
     ReDim ProcessIDs(lProcCount / 4) As Long
     lRet = EnumProcesses(ProcessIDs(1), lProcCount, lProcPoss)
 Loop
 lNum = lProcPoss / 4

 For iCounter = 1 To lNum
     'Get a handle to the Process
     hwndProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ProcessIDs(iCounter))
     'Got a Process handle
     If hwndProcess <> 0 Then
         'Get an array of the module handles for the specified
         'process
         lRet = EnumProcessModules(hwndProcess, arrModules(1), 200, cbNeeded2)
         'If the Module Array is retrieved, Get the ModuleFileName
         If lRet <> 0 Then
             sModName = Space(255)
             lRet = GetModuleFileNameExA(hwndProcess, arrModules(1), sModName, SIZE)
             'Form1.lstProcesses.AddItem ProcessIDs(iCounter) & vbTab & Left(sModName, lRet)
             If UCase(Left(sModName, lRet)) = UCase(strProcess) Then
                 GetProcesses = GetProcesses + 1
             End If
         End If
     End If
     'Close the handle
     lRet = CloseHandle(hwndProcess)
 Next

End Function

Private Sub Form_Load()
    ShellExecute Me.hWnd, "open", "C:\Users\hed-b\Desktop\PulserTester.appref-ms", vbNullString, "C:\", ByVal 1&

    MsgBox GetProcesses("PulserTester")
End Sub

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

简而言之,我尝试从 C# 到 VB6 编写此代码的等效代码

var p = new Process();
            p.StartInfo = new ProcessStartInfo(@"cmd.exe")
            {
                Arguments = @"/c C:\Users\hed-b\Desktop\PulserTester.appref-ms"
            };
            p.Start();
            while(Process.GetProcessesByName("PulserTester").Any() == false)
            { Thread.Sleep(100); }
            p = Process.GetProcessesByName("PulserTester").First();
            p.WaitForExit();

标签: c#processvb6

解决方案


txtnote.seltext是你也可以写的东西。这是一个编辑控件,但它可能是一个文件流。

  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 Process32First 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 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 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


Sub mnuInsertProcessList_Click()
         Dim f As Long, sname As String, PList As String, Ret As Long
         Dim hSnap As Long, proc As PROCESSENTRY32
         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
         If hSnap = hNull Then Exit Sub
         proc.dwSize = LenB(proc)
         ' Iterate through the processes
         txtNote.SelText = "PID:int" & vbTab & "ParentPID:int" & vbTab & "ExeName:string" & vbCrLf
         f = Process32First(hSnap, proc)
         Do
                sname = StrZToStr(proc.szExeFile)
                txtNote.SelText = proc.th32ProcessID
                txtNote.SelText = vbTab
                txtNote.SelText = proc.th32ParentProcessID
                txtNote.SelText = vbTab
                 txtNote.SelText = sname
                txtNote.SelText = vbCrLf
                f = Process32Next(hSnap, proc)
         Loop While f = 1
        Ret = CloseHandle(hSnap)
        If Ret = 0 Then MsgBox Err.LastDllError
 End Sub

 Function StrZToStr(S As String) As String
     StrZToStr = Left$(S, Len(S) - 1)
 End Function

推荐阅读