有两个exes /程序根据命令行参数执行任务,我们称之为Profile。用户可以使用特定的配置文件运行这些exes的多个实例。
我们遇到的情况是,如果一个exe运行一个配置文件,另一个不应该使用相同的配置文件运行,或者一个exe不能使用相同的配置文件实例化两次。为此,我们需要识别具有相同配置文件的运行流程。
一种可能性是记录,但如果进程/ exe终止,它可能会失败。
修改
我需要通过向他/她显示进程'窗口/表单标题来通知用户。由于我的exes是基于表单的,因此每个进程都将根据配置文件拥有自己的标题。基于WMI的解决方案,作为我的答案发布,只能找到带有文件名的进程,WMI没有列出窗口/表单标题的任何功能,所以我决定使用Win32 API。
我使用Code sample from this post因为我只有PID而不是句柄。代码示例没有返回标题。我检查了以下步骤
ProcessID
时未返回任何标题。ParentProcessID
时返回了父exe的正确标题
来自WMI的通过。看起来代码示例不适用于子exe(我的exes是从另一个exe调用的,即我的exes是child,而调用者是parent)。 EnumCallBack
找到的句柄不等于表单hWnd
,这就是它没有返回标题的原因。
答案 0 :(得分:1)
感谢MC ND识别要使用的WMI和Evripidis
以下是获取所有进程的命令行参数的示例代码
Dim objWMIService, objProcess, colProcess
Dim strComputer, strList
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess In colProcess
Debug.Print objProcess.Name & " | " & objProcess.CommandLine
Next
获取已在其命令行参数中传递ABCD
的进程的查询将是
Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process " & _
" Where CommandLine Like ""%ABCD%"" ")
阅读更多
修改:
要从ProcessID获取窗口/表单标题,我使用了以下文章中的源代码 Evripidis
Get window handlle (hWnd) from process ID
这是中心思想
答案 1 :(得分:0)
询问WMI
wmic process get name,commandline
答案 2 :(得分:0)
通常,单个实例程序会创建互斥锁。如果它可以,那么没有其他实例正在运行。如果它不能切换到上一个实例的窗口,然后退出。
在vb6中,app对象具有PrevInstance属性,但这只会提醒您需要检查参数。
因此,请创建一个与您的个人资料同名的互斥锁。
CreateMutex
The CreateMutex function creates or opens a named or unnamed mutex object.
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD
BOOL bInitialOwner, // initial owner
LPCTSTR lpName // object name
);
答案 3 :(得分:0)
这里有一些代码(没有删节,它来自表单,所以你需要编辑它)。它列出了系统中每个窗口的所有内容。
它输出像这样(进入rtfedit)。级别是显示父子关系的缩进数。
Order Level WindowText ClassName HWnd ParentHWnd ProcessID ParentProcessID ThreadID ModuleNameHWin EXENameProcess
1 0 «No Window Text 0» msvb_lib_tooltips 133318 133318 1648 3876 1944 C:\Windows\system32\MSCOMCTL.OCX VB6.EXE
2 0 «No Window Text 0» msvb_lib_tooltips 133316 133318 1648 3876 1944 C:\Windows\system32\MSCOMCTL.OCX VB6.EXE
3 0 «No Window Text 0» msvb_lib_tooltips 198898 133318 1648 3876 1944 C:\Windows\system32\MSCOMCTL.OCX VB6.EXE
4 0 «No Window Text 0» msvb_lib_tooltips 133276 133318 1648 3876 1944 C:\Windows\system32\MSCOMCTL.OCX VB6.EXE
5 0 «No Window Text 0» tooltips_class32 8585400 133318 1648 3876 1944 C:\Program Files\Microsoft Visual Studio\VB98\vb6.exe VB6.EXE
6 0 «No Window Text 0» tooltips_class32 7341130 133318 1648 3876 1944 C:\Program Files\Microsoft Visual Studio\VB98\vb6.exe VB6.EXE
7 0 MSCTFIME UI MSCTFIME UI 8127794 133318 3356 1500 3240 C:\Program Files\Microsoft Visual Studio\VB98\vb6.exe explorer.exe
8 0 Default IME IME 721516 133318 3356 1500 3240 «Not Available Error=0» explorer.exe
9 0 «No Window Text 0» tooltips_class32 7340808 133318 3356 1500 3240 «Not Available Error=0» explorer.exe
10 0 «No Window Text 0» ThumbnailStackClass 4457892 133318 3356 1500 3240 «Not Available Error=0» explorer.exe
这是代码
Sub mnuInsertWindowList_Click()
' WindowChain = 0
Dim hwnd As Long
hwnd = GetTopWindow(0)
If hwnd <> 0 Then
AddChildWindows hwnd, 0
End If
End Sub
Private Function AddChildWindows(ByVal hwndParent As Long, ByVal Level As Long) As String
Dim gwfnhwnd As Long, X As Long, WT As String, CN As String, Length As Long, hwnd As Long, TID As Long, PID As Long, MN As String, Ret As Long, Parenthwnd As Long
Static Order As Long
Static FirstTime As Long
Parenthwnd = hwndParent
If Level = 0 Then
hwnd = hwndParent
Else
hwnd = GetWindow(hwndParent, GW_CHILD)
End If
Do While hwnd <> 0
WT = Space(512)
Length = GetWindowText(hwnd, WT, 508)
WT = Left$(WT, Length)
If WT = "" Then WT = Chr(171) & "No Window Text " & Err.LastDllError & Chr(187)
CN = Space(512)
Length = GetClassName(hwnd, CN, 508)
CN = Left$(CN, Length)
If CN = "" Then CN = "Error=" & Err.LastDllError
TID = GetWindowThreadProcessId(hwnd, PID)
MN = Space(512)
Length = GetWindowModuleFileName(hwnd, MN, 508)
If Length = 0 Then
MN = Chr(171) & "Not Available Error=" & Err.LastDllError & Chr(187)
Else
MN = Left$(MN, Length)
End If
Dim f As Long, sname As String, PList As String, PPID As Long
Dim hSnap As Long, proc As PROCESSENTRY32, Temp As String
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
If hSnap = hNull Then Exit Function
proc.dwSize = LenB(proc)
' Iterate through the processes
f = Process32First(hSnap, proc)
Do
If PID = proc.th32ProcessID Then
sname = StrZToStr(proc.szExeFile)
PPID = proc.th32ParentProcessID
End If
f = Process32Next(hSnap, proc)
Loop While f = 1
Order = Order + 1
' CStr(Order) & " HWnd=" & FormatNumber$(hwnd, 0, vbFalse, vbFalse, vbFalse) & " Parent HWnd=" & FormatNumber$(Parenthwnd, 0, vbFalse, vbFalse, vbFalse) & " Level=" & CStr(Level) & WT & " (" & CN & ")" & " PID=" & FormatNumber$(PID, 0, vbFalse, vbFalse, vbFalse) & " TID=" & FormatNumber$(TID, 0, vbFalse, vbFalse, vbFalse) & " Module Name:" & MN & " ExeName:" & sname & vbCrLf
If FirstTime = 0 Then
txtNote.SelText = vbCrLf & "Order" & vbTab & "Level" & vbTab & "WindowText" & vbTab & "ClassName" & vbTab & "HWnd" & vbTab & "ParentHWnd" & vbTab & "ProcessID" & vbTab & "ParentProcessID" & vbTab & "ThreadID" & vbTab & "ModuleNameHWin" & vbTab & "EXENameProcess"
FirstTime = 1
End If
txtNote.SelText = vbCrLf & CStr(Order) & vbTab & CStr(Level) & vbTab & WT & vbTab & CN & vbTab & CStr(hwnd) & vbTab & CStr(Parenthwnd) & vbTab & CStr(PID) & vbTab & CStr(PPID) & vbTab & CStr(TID) & vbTab & MN & vbTab & sname
AddChildWindows hwnd, Level + 1
hwnd = GetWindow(hwnd, GW_HWNDNEXT)
Loop
End Function
这些是声明。
Public Declare Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function GetWindowModuleFileName Lib "user32" Alias "GetWindowModuleFileNameA" (ByVal hwnd As Long, ByVal WinModule As String, StringLength As Long) As Long
Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Public Declare Function IsUserAnAdmin Lib "Shell32" () As Boolean
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 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 Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2