I'm no sure how is designed ObjGet internally but probably a minor bug because I did a test using ROT which is fast enough.
Test Script:
#include <Excel.au3>
#include <Array.au3>
#include <WinAPI.au3>
Global Const $sIID_IEnumMoniker = '{00000102-0000-0000-c000-000000000046}'
Global Const $sTagIEnumMoniker = "Next hresult(dword;ptr*;dword*);" & _
"Skip hresult(dword);" & _
"Reset hresult();" & _
"Clone hresult(ptr*);"
Global Const $sIID_IMoniker = '{0000000f-0000-0000-C000-000000000046}'
Global Const $sTagIMoniker = "GetClassID hresult( clsid )" & _
"IsDirty hresult( );" & _
"Load hresult( ptr );" & _
"Save hresult( ptr, bool );" & _
"GetSizeMax hresult( uint64 );" & _
"BindToObject hresult( ptr;ptr;clsid;idispatch*);" & _
"BindToStorage hresult( ptr;ptr;clsid;ptr*);" & _
"Reduce hresult( ptr;dword;ptr*;ptr*);" & _
"ComposeWith hresult( ptr;bool;ptr*);" & _
"Enum hresult( bool;ptr*);" & _
"IsEqual hresult( ptr);" & _
"Hash hresult( dword*);" & _
"IsRunning hresult( ptr;ptr;ptr);" & _
"GetTimeOfLastChange hresult( ptr;ptr;int64*);" & _
"Inverse hresult( ptr*);" & _
"CommonPrefixWith hresult( ptr;ptr*);" & _
"RelativePathTo hresult( ptr;ptr*);" & _
"GetDisplayName hresult( ptr;ptr;wstr*);" & _
"ParseDisplayName hresult( ptr;ptr;wstr;ulong*;ptr*);" & _
"IsSystemMoniker hresult( dword*);"
Global Const $IID_IRunningObjectTable = "{00000010-0000-0000-C000-000000000046}"
Global Const $sTagIRunningObjectTable = "Register HRESULT(DWORD;PTR;PTR;DWORD*);" & _
"Revoke HRESULT(DWORD);" & _
"IsRunning HRESULT(PTR*);" & _
"GetObject HRESULT(PTR;PTR*);" & _
"NoteChangeTime HRESULT(DWORD;PTR*);" & _
"GetTimeOfLastChange HRESULT(PTR*;PTR*);" & _
"EnumRunning HRESULT(PTR*);"
Global Const $IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"
Local $oExcel1 = _Excel_Open()
Local $oExcel2 = _Excel_Open(True, False, True, True, True)
Local $oExcel3 = _Excel_Open(True, False, True, True, True)
For $i = 1 To 5
_Excel_BookNew($oExcel1, 1)
_Excel_BookNew($oExcel2, 1)
_Excel_BookNew($oExcel3, 1)
Next
Local $hTimer = TimerInit()
Local $aWorkBooks = _Excel_BookListEx()
_ArrayDisplay($aWorkBooks, " _Excel_BookListEx Time: " & TimerDiff($hTimer))
_Excel_Close($oExcel1)
_Excel_Close($oExcel2)
_Excel_Close($oExcel3)
Func _Excel_BookListEx($oExcel = Default)
Local $aBooks[0][3], $iIndex = 0
If IsObj($oExcel) Then
If ObjName($oExcel, 1) <> "_Application" Then Return SetError(1, 0, 0)
Local $iTemp = $oExcel.Workbooks.Count
ReDim $aBooks[$iTemp][3]
For $iIndex = 0 To $iTemp - 1
$aBooks[$iIndex][0] = $oExcel.Workbooks($iIndex + 1)
$aBooks[$iIndex][1] = $oExcel.Workbooks($iIndex + 1).Name
$aBooks[$iIndex][2] = $oExcel.Workbooks($iIndex + 1).Path
Next
Else
If $oExcel <> Default Then Return SetError(1, 0, 0)
Local $aCall = DllCall("Ole32.dll", "LONG", "GetRunningObjectTable", "DWORD", 0, "PTR*", 0)
Local $pIRunningObjectTable = $aCall[2]
Local $oRunningObjectTable = ObjCreateInterface($pIRunningObjectTable, $IID_IRunningObjectTable, $sTagIRunningObjectTable)
Local $pIEnumMoniker = 0
$oRunningObjectTable.EnumRunning($pIEnumMoniker)
Local $oEnumMoniker = ObjCreateInterface($pIEnumMoniker, $sIID_IEnumMoniker, $sTagIEnumMoniker)
Local $pMoniker = 0
Local $iFetched = 0
Local $oMoniker = 0
Local $pCTX = 0
Local $oWorkBook = 0
$aCall = DllCall("Ole32.dll", "long", "CreateBindCtx", "dword", 0, "ptr*", 0)
$pCTX = $aCall[2]
While $oEnumMoniker.Next(1, $pMoniker, $iFetched) = 0
$oMoniker = ObjCreateInterface($pMoniker, $sIID_IMoniker, $sTagIMoniker)
$oMoniker.BindToObject($pCTX, 0, $IID_IDispatch, $oWorkBook)
If IsObj($oWorkBook) Then
ReDim $aBooks[UBound($aBooks)+1][3]
$aBooks[$iIndex][0] = $oWorkBook
$aBooks[$iIndex][1] = $oWorkBook.Name
$aBooks[$iIndex][2] = $oWorkBook.Path
$iIndex+=1
EndIf
WEnd
EndIf
Return ($iIndex > 0 ? SetError(0, $iIndex, $aBooks) : SetError(1, 0, $aBooks))
EndFunc ;==>_Excel_BookListEx
Saludos