问题
How can I show all the threads or instances of Excel file in vb dot net?
I want to show all the threads and one main process of Excel files. I have seen the process and process id but not a way to show all threads of Excel, meaning if I open three Excel files I can show three files in listbox.
回答1:
I am not sure there is an easy way to do this. Here is some code that I have modified from a similar situation. Firstly here is a class that gets the child window titles from a specified process 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
The class works by using the EnumThreadWindows
function to get a list of the handles of child windows and then uses GetWindowTextLength
and GetWindowText
to get the actual title of those child windows (if they have one).
Here is a simple console app showing how to use the class:
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
This code gets the processes that contain the name EXCEL. There is normally only one of these. It then uses that get all the child windows that have the text '- Excel' in them. This should give you the list you require.
来源:https://stackoverflow.com/questions/57355374/how-to-show-all-the-threads-or-instances-of-excel-file-in-vb-dot-net-i-want-to-s