如何在 vb dot net 中显示 Excel 文件的所有线程或实例?
我想显示Excel文件的所有线程和一个主要进程。我已经看到了进程和进程 ID,但没有显示 Excel 所有线程的方法,这意味着如果我打开三个 Excel 文件,我可以在列表框中显示三个文件。
我不确定有没有简单的方法可以做到这一点。这是我从类似情况修改的一些代码。首先,这是一个从指定进程 ID 获取子窗口标题的类:
Class ChildWindowManager
Delegate Function EnumThreadDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
<DllImport("user32.dll")>
Private Shared Function EnumThreadWindows(ByVal dwThreadId As Integer, ByVal lpfn As EnumThreadDelegate, ByVal lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll")>
Public Shared Function GetWindowText(ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
End Function
<DllImport("user32.dll")>
Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
End Function
Private Shared Function EnumerateProcessWindowHandles(ByVal processId As Integer) As List(Of IntPtr)
Dim windowHandles = New List(Of IntPtr)()
For Each thread As ProcessThread In Process.GetProcessById(processId).Threads
EnumThreadWindows(thread.Id, Function(hWnd, lParam)
windowHandles.Add(hWnd)
Return True
End Function, IntPtr.Zero)
Next
Return windowHandles
End Function
Private Shared Function GetWindowTitle(ByVal hWnd As IntPtr) As String
Dim length As Integer = GetWindowTextLength(hWnd)
If length = 0 Then Return Nothing
Dim titleStringBuilder As New Text.StringBuilder("", length)
GetWindowText(hWnd, titleStringBuilder, titleStringBuilder.Capacity + 1)
Return titleStringBuilder.ToString()
End Function
Public Shared Function GetChildWindowTitles(processId As Integer) As List(Of String)
Dim windowTitles As New List(Of String)
For Each handle In EnumerateProcessWindowHandles(processId)
Dim windowText = GetWindowTitle(handle)
If windowText <> Nothing Then
windowTitles.Add(windowText)
End If
Next
Return windowTitles
End Function
End Class
该类的工作原理是使用 EnumThreadWindows
函数获取子窗口句柄的列表,然后使用 GetWindowTextLength
和 GetWindowText
获取这些子窗口的实际标题(如果有(。
下面是一个简单的控制台应用,展示了如何使用该类:
Imports System.Runtime.InteropServices
Sub Main()
Dim allProcesses = Process.GetProcesses().Where(Function(p) p.ProcessName.Contains("EXCEL"))
Dim windowTitles = ChildWindowManager.GetChildWindowTitles(allProcesses.First().Id)
For Each title In windowTitles
If (title.Contains("- Excel")) Then
Console.WriteLine(title)
End If
Next
Console.ReadLine()
End Sub
此代码获取包含名称 EXCEL 的进程。通常只有其中之一。然后,它使用 获取包含文本"- Excel"的所有子窗口。这应该会为您提供所需的列表。