提问人:Shodan 提问时间:7/26/2023 最后编辑:braXShodan 更新时间:7/26/2023 访问量:32
(2012年 VB.net)从每个正在运行的 Excel 实例中获取“xlApp”?
(In VB.net 2012) Obtain "xlApp" from each running Excel instances?
问:
我正在尝试枚举每个excel实例,然后为每个实例获取“xlApp”对象
注意:您可以通过单击开始菜单中的 Excel 链接来创建多个 Excel 实例,但在启动时按住左 alt 按钮,它会询问您是否要创建新实例
到目前为止,我的代码(编译和运行没有错误,但没有在列表中返回 xlApp 对象)
Imports System.Runtime.InteropServices
Imports System.Text
Imports Excel = Microsoft.Office.Interop.Excel
Module Module1
Private Const EXCEL7 As String = "EXCEL7"
Private Const GW_CHILD As Integer = 5
Private Const GW_HWNDNEXT As Integer = 2
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Function FindWindowEx(ByVal parentHandle As IntPtr, _
ByVal childAfter As IntPtr, _
ByVal className As String, _
ByVal windowTitle As String) As IntPtr
End Function
<DllImport("Oleacc.dll")> _
Private Function AccessibleObjectFromWindow(ByVal hwnd As Integer, _
ByVal dwObjectID As UInteger, _
ByVal riid As Byte(), _
ByRef ptr As Excel.Window) As Integer
End Function
Private Function EnumerateExcelInstances() As System.Collections.Generic.List(Of Excel.Application)
Dim excelInstances As New System.Collections.Generic.List(Of Excel.Application)()
Try
Dim hwnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "XLMAIN", Nothing)
While hwnd <> IntPtr.Zero
Dim hwndChild = FindWindowEx(hwnd, IntPtr.Zero, EXCEL7, Nothing)
If hwndChild <> IntPtr.Zero Then
Dim ptr As Excel.Window = Nothing
Dim guid As New Guid("{00020400-0000-0000-C000-000000000046}")
AccessibleObjectFromWindow(hwndChild.ToInt32(), &HFFFFFFF0UI, guid.ToByteArray(), ptr)
If ptr IsNot Nothing Then
excelInstances.Add(ptr.Application)
End If
End If
hwnd = FindWindowEx(IntPtr.Zero, hwnd, "XLMAIN", Nothing)
End While
Catch ex As Exception
Console.WriteLine("Error: " & ex.Message)
End Try
Return excelInstances
End Function
Sub Main()
Dim excelInstances = EnumerateExcelInstances()
For Each xlApp In excelInstances
Console.WriteLine("Excel Process ID: " & xlApp.Hwnd)
If xlApp.Workbooks.Count > 0 Then
Console.WriteLine("Opened Workbooks:")
For Each wb As Excel.Workbook In xlApp.Workbooks
Console.WriteLine(wb.Name)
Next
Else
Console.WriteLine("No workbooks are open.")
End If
Next
End Sub
End Module
您可以使用以下 vbc 命令将其保存到 listexcel.vb 来编译它(您可能需要将路径调整为 Microsoft.Office.Interop.Excel.dll,并且路径中必须有 vbc)
vbc /r:C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop.Excel\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll /r:System.dll listexcel.vb
您可以使用以下代码列出每个 Excel 进程的每个窗口句柄。(测试工作)
Imports System.Runtime.InteropServices
Imports System.Text
Module Module1
' Define the class name of the Excel application main window
Private Const xlMainWindowClass As String = "XLMAIN"
Sub Main()
Console.WriteLine("Running Excel instances:")
' Enumerate all windows
EnumWindows(Function(hWnd, lParam) As Boolean
' Get the window's class name
Dim className As New StringBuilder(256)
GetClassName(hWnd, className, className.Capacity)
' If the window is an Excel main window, print its handle
If className.ToString() = xlMainWindowClass Then
Console.WriteLine(hWnd.ToString())
End If
' Continue enumeration
Return True
End Function, IntPtr.Zero)
End Sub
' Delegate and methods for EnumWindows
Private Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
<DllImport("user32.dll")>
Private Function EnumWindows(callback As EnumWindowsProc, lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll")>
Private Function GetClassName(hWnd As IntPtr, lpClassName As StringBuilder, nMaxCount As Integer) As Integer
End Function
End Module
您可以用它来编译和测试
vbc /r:C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop.Excel\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll /r:System.dll listexcelpidhwnd.vb
现在,我的目标是为每个正在运行的 excel 实例打印所有工作簿名称,测试代码如下(经过测试工作)
Imports Microsoft.Office.Interop
Module Module1
Sub Main()
Dim xlApp As Excel.Application = Nothing
Dim xlWorkbooks As Excel.Workbooks = Nothing
Try
' Get a reference to Excel
xlApp = DirectCast(System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application"), Excel.Application)
Catch
' If Excel is not running, exit
Console.WriteLine("Excel is not running.")
Return
End Try
' Get a reference to the Workbooks collection
xlWorkbooks = xlApp.Workbooks
' Enumerate the workbooks
If xlWorkbooks.Count > 0 Then
Console.WriteLine("Opened workbooks:")
For i As Integer = 1 To xlWorkbooks.Count
Console.WriteLine(xlWorkbooks.Item(i).Name)
Next
Else
Console.WriteLine("No workbooks are open.")
End If
' Clean up
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlWorkbooks)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
End Sub
End Module
您可以用它来编译和测试
vbc /r:C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop.Excel\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll /r:System.dll listworkbooks.vb
答: 暂无答案
评论