Sign in to follow this  
Followers 0
Ascend4nt

Disk and Device Read/Write Statistics

5 posts in this topic

#1 ·  Posted (edited)

Disk and Device Read/Write (I/O) Statistics


This is an example of getting and displaying Read/Write Activity for all Disks and Device I/O.  The actual UDF function _NTQuerySysPerfInfo() returns a whole lot more Performance Information for the computer; however, we are focused on I/O activitiy here.

This was written as a faster alternative to WMI, as well as an alternative to >Performance Counters (see my >Physical Disk Read/Write activity example).

Update 2013-07-06:

Changed: Renamed module

Changed: _AddCommas now uses a nicer PCRE

Fixed - Copy and paste errors

Added - Comma separators

DiskDeviceIOStatistics.au3

; ========================================================================================================
; <DiskDeviceIOStatistics.au3>
;
; Example of reading and displaying Disk and Device I/O Statistics, using a 'Spash' window
;  NOTE There is alot more data returned from _NTSysPerformanceInfo(), but
;  for our purposes, we focus only on I/O data
;
; Functions:
;    _NTSysPerformanceInfo()        ; Returns I/O and a whole slew of other Performance Info
;
; Author: Ascend4nt
; ========================================================================================================

; ===================================================================================================================
; Func _NTSysPerformanceInfo()
;
; Returns Disk & Device I/O Statistics (and much more) from NtQuerySystemInformation.
;
; NOTE: ZWReadFile and ZWWriteFile are low-level File I/O that are called by higher-level File I/O
;    (such as ReadFile and WriteFile)
;
; Returns:
;  Success: Array of I/O and Performance Stats:
;    [0]  = Idle Time of all CPU's on the system (in 100-nanosecond intervals)
;    [1]  = # of Bytes Read through ZWReadFile calls
;    [2]  = # of Bytes Written through ZWWriteFile calls
;    [3]  = # of Bytes for all Other I/O Operations (such as Device I/O)
;    [4]  = # of calls made to ZWReadFile (NOT the # of bytes - see [1])
;    [5]  = # of calls made to ZWWriteFile (NOT the # of bytes - see [2])
;    [6]  = # of calls to other I/O Operations (such as Device I/O) - see [3]
;    [7]  = # of Physical Pages Available to Processes
;    [8]  = # of Commited Pages of Virtual Memory
;    [9]  = Commit Limit - # of Pages that can be committed before extending PageFile
;    [10] = Peak # of Pages of Committed Virtual Memory
;    [11] = # of Page Faults (soft and hard)
;    [12] = # of Write Faults (attempts to write to copy-on-write pages)
;    [13] = # of Soft Page Faults [TransitionFaults]
;    [14] = # of Demand Zero Faults
;    [15] = # of Pages Read from Disk to Resolve Page Faults
;    [16] = # of Read Operations to Resolve Page Faults [not # of pages]
;    [17] = # of Pages Written to System's Pagefiles
;    [18] = # of Write operations performed on System's Pagefiles
;    .. alot more info (see SYSTEM_PERFORMANCE_INFO structure) ..
;    [73] = # of System Calls
;
;  Failure: "" with @error set:
;     @error = 2: DLLCall error, @extended = error returned from DLLCall
;    @error = 3: NTSTATUS returned error code, @extended contains error code
;
; Author: Ascend4nt
; ===================================================================================================================

Func _NTQuerySysPerfInfo()
#cs
    ; SYSTEM_PERFORMANCE_INFORMATION Defined as size 312 in latest <winternl.h>,
    ;  but on Win7 this is 328 (both 32-bit and 64-bit modes).
    ; For now I've added a buffer at the end of 16 bytes (+ 16 more for future issues).
    ; Hopefully eventually I'll be able to track down what the extra data is.
    ; Its obviously not a 32-bit vs 64-bit size difference..
#ce
    Local Const $tagSYSTEM_PERFORMANCE_INFORMATION = "uint64 IdleTime;uint64 ReadTransferCount;uint64 WriteTransferCount;uint64 OtherTransferCount;" & _
        "ULONG ReadOperationCount;ULONG WriteOperationCount;ULONG OtherOperationCount;" & _
        "ULONG AvailablePages;ULONG TotalCommittedPages;ULONG TotalCommitLimit;ULONG PeakCommitment;" & _
        "ULONG PageFaults;ULONG WriteCopyFaults;ULONG TransitionFaults;ULONG Reserved1;ULONG DemandZeroFaults;ULONG PagesRead;ULONG PageReadIos;" & _
        "ULONG Reserved2[2];ULONG PagefilePagesWritten;ULONG PagefilePageWriteIos;ULONG MappedFilePagesWritten;ULONG MappedFilePageWriteIos;" & _
        "ULONG PagedPoolUsage;ULONG NonPagedPoolUsage;ULONG PagedPoolAllocs;ULONG PagedPoolFrees;ULONG NonPagedPoolAllocs;ULONG NonPagedPoolFrees;" & _
        "ULONG TotalFreeSystemPtes;ULONG SystemCodePage;ULONG TotalSystemDriverPages;ULONG TotalSystemCodePages;" & _
        "ULONG SmallNonPagedLookasideListAllocateHits;ULONG SmallPagedLookasideListAllocateHits;ULONG Reserved3;" & _
        "ULONG MmSystemCachePage;ULONG PagedPoolPage;ULONG SystemDriverPage;" & _
        "ULONG FastReadNoWait;ULONG FastReadWait;ULONG FastReadResourceMiss;ULONG FastReadNotPossible;ULONG FastMdlReadNoWait;" & _
        "ULONG FastMdlReadWait;ULONG FastMdlReadResourceMiss;ULONG FastMdlReadNotPossible;" & _
        "ULONG MapDataNoWait;ULONG MapDataWait;ULONG MapDataNoWaitMiss;ULONG MapDataWaitMiss;" & _
        "ULONG PinMappedDataCount;ULONG PinReadNoWait;ULONG PinReadWait;ULONG PinReadNoWaitMiss;ULONG PinReadWaitMiss;" & _
        "ULONG CopyReadNoWait;ULONG CopyReadWait;ULONG CopyReadNoWaitMiss;ULONG CopyReadWaitMiss;" & _
        "ULONG MdlReadNoWait;ULONG MdlReadWait;ULONG MdlReadNoWaitMiss;ULONG MdlReadWaitMiss;" & _
        "ULONG ReadAheadIos;ULONG LazyWriteIos;ULONG LazyWritePages;ULONG DataFlushes;ULONG DataPages;" & _
        "ULONG ContextSwitches;ULONG FirstLevelTbFills;ULONG SecondLevelTbFills;ULONG SystemCalls;" & "ULONG Buffer[8];"

    Local $stSysPerfInfo,$iSysInfoLen

    $stSysPerfInfo = DllStructCreate($tagSYSTEM_PERFORMANCE_INFORMATION)
    $iSysInfoLen = DllStructGetSize($stSysPerfInfo)

;~     ConsoleWrite("SYSTEM_PERFORMANCE_INFORMATION structure size:" & $iSysInfoLen & @CRLF)

    ; SystemPerformanceInformation = class 2
    Local $aRet=DllCall("ntdll.dll","long","NtQuerySystemInformation","int",2,"ptr",DllStructGetPtr($stSysPerfInfo),"ulong",$iSysInfoLen,"ulong*",0)
    If @error Then Return SetError(2, @error, "")

    ; NTSTATUS of something OTHER than success?
    If $aRet[0] Then
;~         If $aRet[0] = 0xC0000004 Then ConsoleWrite("STATUS_INFO_LENGTH_MISMATCH, size required: " &$aRet[4] & @CRLF)
        Return SetError(3, $aRet[0], "")
    EndIf

;~     If $aRet[4]<>$iSysInfoLen Then ConsoleWriteError("Size mismatch: $stInfo struct length="&$iSysInfoLen&", ReturnLength="&$aRet[4]&@LF)

;~     _DLLStructDisplay($stSysPerfInfo, $tagSYSTEM_PERFORMANCE_INFORMATION)

    Dim $aRet[74]
    For $i = 1 To 74
        $aRet[$i - 1] = DllStructGetData($stSysPerfInfo, $i)
    Next
    Return $aRet
EndFunc


; ====================================================================================================
; Func _AddCommas($sString)
;
; Simple PCRE to add commas - borrowed from StackOverflow
; "regex - Insert commas into number string" - answer by toolkit:
; @ http://stackoverflow.com/a/721415
;
; Author: Ascend4nt
; ====================================================================================================

Func _AddCommas($sString)
    Return StringRegExpReplace($sString, "(\d)(?=(\d{3})+$)", "$1,")
EndFunc


;   --------------------    HOTKEY FUNCTION & VARIABLE --------------------

Global $bHotKeyPressed = False

Func _EscPressed()
    $bHotKeyPressed=True
EndFunc

;   --------------------    MAIN PROGRAM CODE   --------------------

HotKeySet("{Esc}", "_EscPressed")

Local $hSplash, $sSplashText
Local $aIOStats


$aIOStats = _NTQuerySysPerfInfo()
If @error Then
    Exit ConsoleWrite("@error = " &@error & ", @extended = " &Hex(@extended) & @CRLF)
EndIf

ConsoleWrite(" I/O Stats: Read = " & _AddCommas($aIOStats[1]) & "; Write = " & _AddCommas($aIOStats[2]) & "; Other = " & _AddCommas($aIOStats[3]) & @CRLF)

$hSplash=SplashTextOn("Hard Drive Usage Information", "", 740, 24 + (4 * 15), Default, Default, 16+4, "Lucida Console", 11)

; Start loop
Do
    $aIOStats = _NTQuerySysPerfInfo()
    $sSplashText  = StringFormat("%50s", "== I/O Stats ==") & @CRLF
    $sSplashText &= StringFormat("Read = %20s | Write = %20s | Other = %20s", _AddCommas($aIOStats[1]), _AddCommas($aIOStats[2]), _AddCommas($aIOStats[3])) & @CRLF

    $sSplashText &= @CRLF & StringFormat("%48s", "[ESC] Exits") & @CRLF

    ControlSetText($hSplash, "", "[CLASS:Static; INSTANCE:1]", $sSplashText)

    Sleep(500)
Until $bHotKeyPressed
Edited by Ascend4nt
3 people like this

Share this post


Link to post
Share on other sites



Small changes - renamed module, changed _AddCommas() function. See 1st post

Share this post


Link to post
Share on other sites

Very nice. I also like the regular expression you found.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Very nice. I also like the regular expression you found.

 

[reference: StringRegExpReplace($sString, "(d)(?=(d{3})+$)", "$1,")]

You know, that regular expression was difficult to understand at first.  I got caught up on thinking about look-aheads as very definitive expressions, but this one allows any number of groups-of-3-digits - or maybe I should say,  a multiple of 3. It's actually quite clever when you understand how it moves from left to right picking off only those numbers followed by 3^x digits.  Seems there's always something new to learn in regular expressions :)

Share this post


Link to post
Share on other sites

True, I read it as though it was d{3,} but yeah I learn something new everyday about regular expressions.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • dzlee
      By dzlee
      hello autoit developers community
      i have some question , i hope to find the answers of it :
      - in large project or even in small ones
      how to make my compiled script use less memory ?
      - how to test my script and be sure that there is no memory leak , or whatsoever reduce my script performance ?
      - where can i find anything talks about autoit script architecture to avoid bad script design ?

      last thing i find these script
      can anyone describe how these scripts work and is these script actually work fine
      thanks
      Func _ReduceMemory() Local $ai_GetCurrentProcessId = DllCall('kernel32.dll', 'int', 'GetCurrentProcessId') Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $ai_GetCurrentProcessId[0]) Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0]) DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0]) Return $ai_Return[0] EndFunc Func _SelfReduceMemory() DllCall("psapi.dll", "int", "EmptyWorkingSet", "long", -1) EndFunc  
    • Ascend4nt
      By Ascend4nt
      Process CPU Usage Trackers

      As yet another alternative to the Performance Counters UDF, I've created this UDF to allow easy tracking of one or more processes's CPU usage.  While this has obviously been done before, I haven't seen it done the way I've created it.
      Basically, just as the Performance Counters had Process Counter objects, so this too has Process Usage trackers.  They are relatively simple to use, and require very little interaction other than invoking the functions.
      To create a new tracker object, call one of these:
      _ProcessUsageTracker_Create()   ; Single process tracker _ProcessesUsageTracker_Create() ; Multiple processes tracker The multiple-process tracker requires addition of processes, which can be done one of 2 ways:
      _ProcessesUsageTracker_Add()  ; add a single  process _ProcessesUsageTracker_AddMultiple()  ; multiple processes in a ProcessList-style array After the usage tracker object has been created, stats can be collected via one of two calls:
      _ProcessUsageTracker_GetUsage()  ; single process - returns a percentage _ProcessesUsageTracker_GetUsage()  ; multiple Processes - returns an array of %'s Basically the main loop of the program can be filled with 'GetUsage' calls without juggling anything around.  If a process dies out, an @error code will be returned in the single-process version.  The multiple-process tracker version however lets you retain dead processes in the list although their process handles will be closed.  These can be alternatively cleared up on each call to 'GetUsage' (setting $bRemoveDead to True), or you can opt to clean them up with the following call:
      _ProcessesUsageTracker_RemoveDead() ; Removes any dead processes from the tracker object Finally, to destroy the trackers and close handles, just call the appropriate function:
      _ProcessUsageTracker_Destroy() _ProcessesUsageTracker_Destroy() That's about it.  More info is in the headers.
      Here's an example of a single process cpu usage tracker:
      ; ======================================================================================================== ; <Process_CPUUsageExample.au3> ; ; Example usage of <Process_CPUUsage.au3> ; ; Author: Ascend4nt ; ======================================================================================================== #include "Process_CPUUsage.au3" ;   --------------------    HOTKEY FUNCTION & VARIABLE -------------------- Global $bHotKeyPressed=False Func _EscPressed()     $bHotKeyPressed=True EndFunc ;   --------------------    MAIN PROGRAM CODE   -------------------- HotKeySet("{Esc}", "_EscPressed") Local $hSplash, $sSplashText Local $sProcess, $aProcUsage, $fUsage ; Regular Process: ;~ $sProcess = "firefox.exe" ;~ $sProcess = "sp2004.exe"    ; Stress Prime 2004 ; Protected Process (opens a different way): ;~ $sProcess = "audiodg.exe" ; Processes Requiring elevated privilege (will fail even with limited access rights): ;~ $sProcess = "CTAudSvc.exe" $sProcess = InputBox("Enter Process Name", "Process Name:", "", "", 320, 140) If @error Or $sProcess = "" Then Exit $aProcUsage = _ProcessUsageTracker_Create($sProcess) If @error Then Exit ConsoleWrite("Error calling _ProcessUsageTracker_Create(): " & @error & ", @extended = " & @extended & @CRLF) Sleep(250) $hSplash=SplashTextOn("Process CPU Usage Information", "", 360, 20 + 60, Default, Default, 16, Default, 12) ; Start loop Do     $sSplashText=""     $fUsage = _ProcessUsageTracker_GetUsage($aProcUsage)     If @error Then         ConsoleWrite("Error from _ProcessUsageTracker_GetUsage(): " & @error & ", @extended = " &@extended & @CRLF)         ExitLoop     EndIf     $sSplashText &= "'"&$sProcess&"' CPU usage: " & $fUsage & " %" & @CRLF     $sSplashText &= @CRLF & "[Esc] exits"     ControlSetText($hSplash, "", "[CLASS:Static; INSTANCE:1]", $sSplashText)     Sleep(500) Until $bHotKeyPressed _ProcessUsageTracker_Destroy($aProcUsage) _
      Multiple processes example, which is best used with something like 'chrome' which spawns a number of processes with the same name:
      ; ======================================================================================================== ; <Processes_CPUUsageExample.au3> ; ; Example usage of <Processes_CPUUsage.au3> ; ; Author: Ascend4nt ; ======================================================================================================== #include "Processes_CPUUsage.au3" ;   --------------------    HOTKEY FUNCTION & VARIABLE -------------------- Global $bHotKeyPressed=False Func _EscPressed()     $bHotKeyPressed=True EndFunc ;   --------------------    MAIN PROGRAM CODE   -------------------- HotKeySet("{Esc}", "_EscPressed") Local $hSplash, $sSplashText Local $sProcess, $aProcList, $aProcUsage, $aPercents, $nPercents ; Regular Process: ;~ $sProcess = "firefox.exe" ;~ $sProcess = "sp2004.exe"    ; Stress Prime 2004 ; Protected Process (opens a different way): ;~ $sProcess = "audiodg.exe" ; Processes Requiring elevated privilege (will fail even with limited access rights): ;~ $sProcess = "CTAudSvc.exe" $sProcess = InputBox("Enter Process Name", "Process Name:", "", "", 320, 140) If @error Or $sProcess = "" Then Exit $aProcUsage = _ProcessesUsageTracker_Create() _ProcessesUsageTracker_Add($aProcUsage, "sp2004.exe") _ProcessesUsageTracker_Add($aProcUsage, "CPUStabTest.exe") $aProcList = ProcessList("chrome.exe") _ProcessesUsageTracker_AddMultiple($aProcUsage, $aProcList) _ProcessesUsageTracker_Add($aProcUsage, $sProcess) _ProcessesUsageTracker_Add($aProcUsage, "audiodg.exe") Sleep(250) $hSplash=SplashTextOn("Process CPU Usage Information", "", 380, 24 + 15*2 + $aProcUsage[0][0]*15, Default, Default, 16+4, "Lucida Console", 11) ; Start loop Do     ; DEBUG: Interrupt to allow multiple process termination     ;MsgBox(0, "Next usage", "Next usage time..")     $sSplashText=""     $aPercents = _ProcessesUsageTracker_GetUsage($aProcUsage, True)    ; True = Remove dead     $nPercents = @extended     If @error Then         ConsoleWrite("Error from _ProcessesUsageTracker_GetUsage(): " & @error & ", @extended = " &@extended & @CRLF)         ExitLoop     EndIf     For $i = 0 To $nPercents - 1         $sSplashText &= "'"&$aProcUsage[$i+1][0]&"' [PID #"&$aProcUsage[$i+1][1]&"] CPU usage: " & $aPercents[$i] & " %" & @CRLF     Next     $sSplashText &= @CRLF & "[Esc] exits"     ControlSetText($hSplash, "", "[CLASS:Static; INSTANCE:1]", $sSplashText)     Sleep(500) Until $bHotKeyPressed _ProcessesUsageTracker_Destroy($aProcUsage) ProcessCPUUsage.zip
    • Ascend4nt
      By Ascend4nt
      Network Interface Info, Statistics, and Traffic (incl. IP, TCP, UDP and ICMP)

      This is an example of getting and displaying Network Interface Information, Statistics and Traffic.  Previously this was just a means to getting Network statistics (specifically IP, TCP, UDP, and ICMP), but now it includes Internet Interface information, as well as Interface-specific statistics.
      Since this UDF can be used in different ways, let me cover Statistics first:
      Network Statistics Information

      Stats example output
       
      To retrieve Statistics information, you can call one of the four _Network_xxxxStatistics() functions for IP, TCP, UDP, or ICMP Statistics.  These functions accept 1 argument which specifies which protocol to use.  Basically, zero is IPv4 and non-zero is IPv6.  It defaults to IPv4 if no arguments.  Here's the functions:
      Protocol Statistics Functions: _Network_IPStatistics() -> receives IP statistics _Network_TCPStatistics() -> TCP statistics _Network_UDPStatistics() -> UDP statistics _Network_ICMPStatistics() -> ICMP statistics -
      To get per-interface statistics requires 2 calls.  One call is required to collect information on adapters into an array. Once this information is retrieved, multiple calls to _Network_InterfaceEntryInfo() can be made for each indexed network interface.  Note that _Network_IPv4AdaptersInfo() is the only adapter/interface information function which doesn't get index information - so don't use it unless you want further interface information.  The main UDF functions to use are:
      Network Adapter & Interface Functions: _Network_IPv4AdaptersInfo() -> Retrieves information on Physical IPv4 adapters _Network_IPv4AdaptersInfoEx() -> Retrieves much more info on Physical IPv4 adapters _Network_IPv4AddressTable() -> Retrieves information on IPv4 Interfaces _Network_IPAllAddressTable() -> Retrieves information on both IPv4 and IPv6 interfaces Network Statistics for a Given Interface: _Network_InterfaceEntryInfo() -> For a given interface index, retrieves statistics -
      The simplest way to get overall traffic is to use _Network_IPAllAddressTable() (or _Network_IPv4AddressTable() for IPv4 only) to collect an array of info about interfaces.  This needs to be done only once.  Then, to collect statistics, for each row in the interface array, call _Network_InterfaceEntryInfo() with $aIPAddressTable[$i][0] to get the statistics for that network interface.
      IMPORTANT: Note that for all statistics, the data received/sent are represented as 32-bit numbers, and subject to wraparound after 4GBs of data has been transferred.
      Network Interface Information
      Regarding Network Interface Information, nearly every function except those ending in xxStatistics(), will return various info regarding the network adapters or interfaces.
      Currently, IPv4 and IPv6 addresses are retrieved for the interface, as well as for Gateway, DHCP, DNS and WINS servers (there's some XP issues here as to which functions to use - see UDFs).  The number of IP addresses (since there can be more than one assigned to each interface) is controlled via a parameter $bGetAllIPs.  If this value is non-zero, multiple IP addresses are returned in a string separated by "|" (pipe symbol).
      Also note that the MAC/Physical Address is returned by most functions as well.  These are properly formatted into a hex string in the form "01-23-45-67-89-ab".
      There is one issue with converting IPv6 addresses - on pre-Vista O/S's (Win XP I'm looking at you) WSAStartup must be called by the code.  This is all handled internally, but if you have code that relies on WSAStartup/Cleanup, keep it in mind and let me know if I can better accommodate any potential conflicts.
      Further notes:
      - The TCP Statistics gives information about the number of segments sent/received, rather than the # of packets.  I'm not totally clear on the association, however here's some links:
       What's the difference between a TCP segment and a TCP packet?
       Whats the difference between a Packet, Segment and Frame?
         
      - I'm not sure how segments, packets, or datagrams map to # of bytes, or what API functions I might use to figure this out. Any help there would be appreciated.
      Alternatives:
      While I have opened access to a lot of detailed network and performance information, there are alternatives - check out Netstat (-e for performance stats) or my >Performance Counters UDF's, which has a lot of varied stats (one example of these: >Network Usage).
      Following is the example, included in the ZIP file.  Note there's a cr@pload of info dumped to the console, so you'll probably want to redirect output or copy-and-paste from the output console:
      ; ======================================================================================================== ; <NetworkStatsExample.au3> ; ; Example of reading and displaying Network Interface Information and Statistics ; (using <NetworkStatistics.au3> UDF) ; Statistics information, including IP, TCP*, UDP, and ICMP and internet interface traffic, ; are displayed in a 'Splash' window - with both IPv4 and IPv6 data separated ; ; Author: Ascend4nt ; ======================================================================================================== #include "_NetworkStatistics.au3" ;   --------------------    HOTKEY FUNCTION & VARIABLE -------------------- Global $bHotKeyPressed = False Func _EscPressed()     $bHotKeyPressed=True EndFunc ;   --------------------    MAIN PROGRAM CODE   -------------------- HotKeySet("{Esc}", "_EscPressed") Local $hSplash, $sSplashText ; Network Stats Local $aUDPStats, $aTCPStats, $aIPStats, $aICMPStats Local $aUDPv6Stats, $aTCPv6Stats, $aIPv6Stats, $aICMPv6Stats Local $aIPv4Adapters, $nAdapters Local $aIPv4AddrTable, $aIPAllAddrTable, $nInterfaces, $aNIEntryInfo Local $sSeparator = "-----------------------------------------" ; IP Stats: IPv4 and IPv6 For $i = 0 To 1     $aIPStats = _Network_IPStatistics($i)     If @error Then         ConsoleWrite("_Network_IPStatistics("&$i&") error: "&@error&", @extended="&@extended&@CRLF)         ContinueLoop     EndIf     If $i Then         ConsoleWrite("IP [IPv6] Stats:")     Else         ConsoleWrite("IP [IPv4] Stats:")     EndIf     ConsoleWrite( _         " [0]  = IP Forwarding Status: [1 = Enabled, 2 = Disabled] : " & $aIPStats[0] & _         ", [1]  = Default initial time-to-live (TTL) for datagrams : " & $aIPStats[1] & @CRLF & _         ", [2]  = # Received Datagrams : " & $aIPStats[2] & _         ", [3]  = # Received Datagrams w/Header errors : " & $aIPStats[3] & _         ", [4]  = # Received Datagrams w/Address errors : " & $aIPStats[4] & @CRLF & _         ", [5]  = # Forwarded Datagrams : " & $aIPStats[5] & _         ", [6]  = # Received Datagrams w/Unknown Protocol : " & $aIPStats[6] & _         ", [7]  = # Received Datagrams Discarded : " & $aIPStats[7] & @CRLF & _         ", [8]  = # Received Datagrams Delivered : " & $aIPStats[8] & _         ", [9]  = # Requested Outgoing Datagrams : " & $aIPStats[9] & _         ", [10] = # Outgoing Datagrams Discarded : " & $aIPStats[10] & @CRLF & _         ", [11] = # Transmitted Datagrams Discarded : " & $aIPStats[11] & _         ", [12] = # Datagrams w/o Routes that were Discarded : " & $aIPStats[12] & _         ", [13] = TimeOut for Reassembling Incoming Fragmented Datagrams : " & $aIPStats[13] & @CRLF & _         ", [14] = # Datagrams Requiring Reassembly : " & $aIPStats[14] & _         ", [15] = # Datagrams Successfully Reassembled : " & $aIPStats[15] & _         ", [16] = # Datagrams that Failed to be Reassembled : " & $aIPStats[16] & @CRLF & _         ", [17] = # Datagrams that were Fragmented Successfully : " & $aIPStats[17] & _         ", [18] = # Datagrams not Fragmented, and Discarded : " & $aIPStats[18] & _         ", [19] = # Fragments created (for Datagrams) : " & $aIPStats[19] & @CRLF & _         ", [20] = # of Interfaces : " & $aIPStats[20] & _         ", [21] = # of IP addresses associated with PC : " & $aIPStats[21] & _         ", [22] = # of Routes in the Routing table : " & $aIPStats[22] & _         @CRLF)     ConsoleWrite($sSeparator & @CRLF) Next ; TCP Stats: IPv4 and IPv6 For $i = 0 To 1     $aTCPStats = _Network_TCPStatistics($i)     If @error Then         ConsoleWrite("_Network_TCPStatistics("&$i&") error: "&@error&", @extended="&@extended&@CRLF)         ContinueLoop     EndIf     If $i Then         ConsoleWrite("TCP [IPv6] Stats:")     Else         ConsoleWrite("TCP [IPv4] Stats:")     EndIf     ConsoleWrite( _         "[0] Rto Algorithm = " & $aTCPStats[0] & _         ",[1] Rto Min = " & $aTCPStats[1] & _         ",[2] Rto Max = " & $aTCPStats[2] & _         ",[3] #Max Connections = " & $aTCPStats[3] & _         ",[4] #Active Opens = " & $aTCPStats[4] & _         ",[5] #Passive Opens = " & $aTCPStats[5] & @CRLF & _         " [6] #Failed Connection Attempts = " & $aTCPStats[6] & _         ",[7] #Established Connections that were Reset = " & $aTCPStats[7] & _         ",[8] #Established Connections [current] = " & $aTCPStats[8] & @CRLF & _         " [9] #Recvd Segments = " & $aTCPStats[9] & _         ",[10] #Sent Segments = " & $aTCPStats[10] & _         ",[11] #Retransmitted Segments = " & $aTCPStats[11] & @CRLF & _         " [12] #Receive Errors = " & $aTCPStats[12] & _         ",[13] #Sent Segments with Reset Flag = " & $aTCPStats[13] & _         ",[14] #Connections = " & $aTCPStats[14] & _         @CRLF)     ConsoleWrite($sSeparator & @CRLF) Next ; UDP Stats: IPv4 and IPv6 For $i = 0 To 1     $aUDPStats = _Network_UDPStatistics($i)     If @error Then         ConsoleWrite("_Network_UDPStatistics("&$i&") error: "&@error&", @extended="&@extended&@CRLF)         ContinueLoop     EndIf     If $i Then         ConsoleWrite("UDP [IPv6] Stats:")     Else         ConsoleWrite("UDP [IPv4] Stats:")     EndIf     ConsoleWrite( _         " [0] #Recvd Datagrams = " & $aUDPStats[0] & _         ",[1] #Discarded Datagrams [invalid port] = " & $aUDPStats[1] & _         ",[2] #Erroneous Datagrams = " & $aUDPStats[2] & @CRLF & _         " [3] #Sent Datagrams = " & $aUDPStats[3] & _         ",[4] #UDP Listener Entries = " & $aUDPStats[4] & _         @CRLF)     ConsoleWrite($sSeparator & @CRLF) Next ; ICMP Stats: IPv4 and IPv6 For $i = 0 To 1     $aICMPStats = _Network_ICMPStatistics($i)     If @error Then         ConsoleWrite("_Network_ICMPStatistics("&$i&") error: "&@error&", @extended="&@extended&@CRLF)         ContinueLoop     EndIf     ConsoleWrite("ICMP [IPv"&4+($i*2)&"] Stats:" & _         " [0] = # Incoming ICMP Messages : " & $aICMPStats[0] & _         ", [1] = # Incoming ICMP Errors : " & $aICMPStats[1] & _         ", [2] = # Outgoing ICMP Messages : " & $aICMPStats[2] & _         ", [3] = # Outgoing ICMP Errors : " & $aICMPStats[3] & _         @CRLF)     ConsoleWrite($sSeparator & @CRLF) Next ; IPv4 Adapters Info (very basic info) _Network_IPv4AdaptersInfo() ConsoleWrite($sSeparator & @CRLF) ; IPv4 Adapters Info (comprehensive info) $aIPv4Adapters = _Network_IPv4AdaptersInfoEx() $nAdapters = @extended ConsoleWrite("# of Adapters: "&$nAdapters&@CRLF) For $i = 0 To $nAdapters - 1     ConsoleWrite("Adapter #"&$i+1&":" & _         "  [0] Index #"& $aIPv4Adapters[$i][0] & _         ", [1] Type = " & $aIPv4Adapters[$i][1] & _         ", [2] DHCP Enabled Flag = " & $aIPv4Adapters[$i][2] & _         ", [3] WINS Enabled Flag = " & $aIPv4Adapters[$i][3] & _         ", [4] Physical [MAC] Address: " & $aIPv4Adapters[$i][4] & _         ", [5] (0) =  " & $aIPv4Adapters[$i][5] & @CRLF & _         ", [6] Description: "& $aIPv4Adapters[$i][6] & _         ", [7] [Empty '']: " & $aIPv4Adapters[$i][7] & _         ", [8] Adapter/Service Name [GUID] = " & $aIPv4Adapters[$i][8] & _         ", [9]  [Empty] =  " & $aIPv4Adapters[$i][9] & _         ", [10] [Empty] =  " & $aIPv4Adapters[$i][10] & @CRLF & _         ", [11] IPv4 Address(es): "& $aIPv4Adapters[$i][11] & _         ", [12] IP Address Mask(s): "& $aIPv4Adapters[$i][12] & @CRLF & _         ", [13] Gateway IPv4 Address(es): "& $aIPv4Adapters[$i][13] & _         ", [14] Gateway Address Mask(s) : "& $aIPv4Adapters[$i][14] & @CRLF & _         ", [15] DHCP IPv4 Address(es) = " & $aIPv4Adapters[$i][15] & _         ", [16] DHCP Address Mask(s)  = " & $aIPv4Adapters[$i][16] & _         ", [17] DHCP LeaseObtained Time = " & $aIPv4Adapters[$i][17] & _         ", [18] DHCP LeaseExpires Time = " & $aIPv4Adapters[$i][18] & @CRLF & _         ", [19] Primary WINS Server IP = " & $aIPv4Adapters[$i][19] & _         ", [20] Primary WINS Server Address Mask = " & $aIPv4Adapters[$i][20] & _         ", [21] Secondary WINS Server IP(s) = " & $aIPv4Adapters[$i][21] & _         ", [22] Secondary WINS Server Address Mask(s) = " & $aIPv4Adapters[$i][22] & @CRLF)     ConsoleWrite($sSeparator & @CRLF) Next ; IPv4 Interface Info alt #2 $aIPv4AddrTable = _Network_IPv4AddressTable() $nInterfaces = @extended ConsoleWrite(@CRLF) For $i = 0 To $nInterfaces - 1     ConsoleWrite("Adapter #"&$i+1&": [0] Interface Index # = " & $aIPv4AddrTable[$i][0] & _         ", [1] IPv4 Address = " & $aIPv4AddrTable[$i][1] & _         ", [2] Subnet Mask = " & $aIPv4AddrTable[$i][2] & _         ", [3] Broadcast Address = " & $aIPv4AddrTable[$i][3] & @CRLF & _         "  [4] Max Reassembly Size = " & $aIPv4AddrTable[$i][4] & _         ", [5] Address Type/State = " & $aIPv4AddrTable[$i][5] & @CRLF) Next ConsoleWrite($sSeparator & @CRLF) ; IPv4 and IPv6 Interface Info (includes everything except Address Masks) ;  params: 0 (IPv4 AND IPv6), 0 (don't get all IP's), 0 (don't include down-status interfaces) $aIPAllAddrTable = _Network_IPAllAddressTable(0, 0, 0) $nInterfaces = @extended ConsoleWrite($sSeparator & @CRLF) For $i = 0 To $nInterfaces - 1     ConsoleWrite("Interface #"&$i+1&": [0] Index #"& $aIPAllAddrTable[$i][0] & _         ", [1] Type = " & $aIPAllAddrTable[$i][1] & _         ", [2] Operational Status = " & $aIPAllAddrTable[$i][2] & _         ", [3] Flags = 0x" & Hex($aIPAllAddrTable[$i][3], 8) & _         ", [4] Physical [MAC] Address: " & $aIPAllAddrTable[$i][4] & _         ", [5] MTU =  " & $aIPAllAddrTable[$i][5] & @CRLF & _         ", [6] Description: "& $aIPAllAddrTable[$i][6] & _         ", [7] Friendly Name: " & $aIPAllAddrTable[$i][7] & _         ", [8] Adapter/Service Name [GUID] = " & $aIPAllAddrTable[$i][8] & @CRLF & _         ", [9] Max Receive Speed [Vista+] = " & $aIPAllAddrTable[$i][9] & _         ", [10] Max Transmit Speed [Vista+] = " & $aIPAllAddrTable[$i][10] & @CRLF & _         ", [11] IPv4 Address(es): "& $aIPAllAddrTable[$i][11] & _         ", [12] IPv6 Address(es): "& $aIPAllAddrTable[$i][12] & @CRLF & _         ", [13] DNS IPv4 Address(es): "& $aIPAllAddrTable[$i][13] & _         ", [14] DNS IPv6 Address(es): "& $aIPAllAddrTable[$i][14] & @CRLF & _         ", [15] Gateway IPv4 Address(es) [Vista+]: "& $aIPAllAddrTable[$i][15] & _         ", [16] Gateway IPv6 Address(es) [Vista+]: "& $aIPAllAddrTable[$i][16] & @CRLF & _         ", [17] DHCP IPv4 Address(es) [Vista+]: "& $aIPAllAddrTable[$i][17] & _         ", [18] DHCP IPv6 Address(es) [Vista+]: "& $aIPAllAddrTable[$i][18] & @CRLF & _         ", [19] WINS IPv4 Address(es) [Vista+]: "& $aIPAllAddrTable[$i][19] & _         ", [20] WINS IPv6 Address(es) [Vista+]: "& $aIPAllAddrTable[$i][20] & @CRLF & _         ", [21] Connection Type [Vista+] = " & $aIPAllAddrTable[$i][21] & _         ", [22] Tunnel Type [Vista+] = " & $aIPAllAddrTable[$i][22] & @CRLF)     ; Interface Statistics & Info for Given index     $aNIEntryInfo = _Network_InterfaceEntryInfo($aIPAllAddrTable[$i][0]) ;~     ConsoleWrite("_Network_InterfaceEntryInfo return, @error = " & @error & ", @extended = " & @extended & @CRLF)     ConsoleWrite("Interface #"&$i+1&" Entry Info: [0] Interface Index = " & $aNIEntryInfo[0] & _         ", [1] Interface Type = " & $aNIEntryInfo[1] & _         ", [2] Operational Status = " & $aNIEntryInfo[2] & _         ", [3] Admin Status = " & $aNIEntryInfo[3] & _         ", [4] Physical Address = " & $aNIEntryInfo[4] & _         ", [5] MTU [Max Trans. Unit] in bytes = " & $aNIEntryInfo[5] & @CRLF & _         ", [6] Description = " & $aNIEntryInfo[6] & _         ", [7] Interface Name = " & $aNIEntryInfo[7] & @CRLF & _         ", [8] Last change [1/100th second] = " & $aNIEntryInfo[8] & _         ", [9] Interface Speed [bps] = " & $aNIEntryInfo[9] & @CRLF & _         ", [10] # Recvd Data [in Octets] = " & $aNIEntryInfo[10] & _         ", [11] # Recvd Unicast Packets = " & $aNIEntryInfo[11] & _         ", [12] # Recvd Non-Unicast Packets = " & $aNIEntryInfo[12] & _         ", [13] # Recvd Packets Discarded [no error] = " & $aNIEntryInfo[13] & _         ", [14] # Recvd Packets Discarded [error] = " & $aNIEntryInfo[14] & _         ", [15] # Recvd Packets Discarded [unk. protocol] = " & $aNIEntryInfo[15] & @CRLF & _         ", [16] # Sent Data [in Octets] = " & $aNIEntryInfo[16] & _         ", [17] # Sent Unicast Packets = " & $aNIEntryInfo[17] & _         ", [18] # Sent Non-Unicast Packets = " & $aNIEntryInfo[18] & _         ", [19] # Sent Packets Discarded [no error] = " & $aNIEntryInfo[19] & _         ", [20] # Sent Packets Discarded [error] = " & $aNIEntryInfo[20] & @CRLF & _         ", [21] Transmit Queue Length [n/a] = " & $aNIEntryInfo[21] & @CRLF)     ConsoleWrite($sSeparator & @CRLF) Next $hSplash=SplashTextOn("Network Usage Information", "", 520, 24 + (19 * 15) + ($nInterfaces * (5.5 * 15)), Default, Default, 16+4, "Lucida Console", 11) ; Start loop Do     $aIPStats   = _Network_IPStatistics()     $aTCPStats  = _Network_TCPStatistics()     $aUDPStats  = _Network_UDPStatistics()     $aICMPStats = _Network_ICMPStatistics()     $aIPv6Stats   = _Network_IPStatistics(1)     $aTCPv6Stats  = _Network_TCPStatistics(1)     $aUDPv6Stats  = _Network_UDPStatistics(1)     $aICMPv6Stats = _Network_ICMPStatistics(1)     $sSplashText  = StringFormat("%35s", "== TCP Stats ==") & @CRLF     $sSplashText &= StringFormat("IPv4: [Segments] Recvd   = %10u | Sent = %10u", $aTCPStats[9], $aTCPStats[10]) & @CRLF     $sSplashText &= StringFormat("IPv6: [Segments] Recvd   = %10u | Sent = %10u", $aTCPv6Stats[9], $aTCPv6Stats[10]) & @CRLF     $sSplashText &= StringFormat("<Total Connections> IPv4:  %10u | IPv6:  %10u", $aTCPStats[14], $aTCPv6Stats[14]) & @CRLF     $sSplashText &= @CRLF & StringFormat("%35s", "== UDP Stats ==") & @CRLF     $sSplashText &= StringFormat("IPv4: [Datagrams] Recvd  = %10u | Sent = %10u", $aUDPStats[0], $aUDPStats[3]) & @CRLF     $sSplashText &= StringFormat("IPv6: [Datagrams] Recvd  = %10u | Sent = %10u", $aUDPv6Stats[0], $aUDPv6Stats[3]) & @CRLF     $sSplashText &= StringFormat("<Total Listeners>   IPv4:  %10u | IPv6:  %10u", $aUDPStats[4], $aUDPv6Stats[4]) & @CRLF     $sSplashText &= @CRLF & StringFormat("%35s", "== IP Stats ==") & @CRLF     $sSplashText &= StringFormat("IPv4: [Datagrams] Recvd  = %10u | Sent = %10u", $aIPStats[2], $aIPStats[9]) & @CRLF     $sSplashText &= StringFormat("IPv6: [Datagrams] Recvd  = %10u | Sent = %10u", $aIPv6Stats[2], $aIPv6Stats[9]) & @CRLF     $sSplashText &= @CRLF & StringFormat("%35s", "== ICMP Stats ==") & @CRLF     $sSplashText &= StringFormat("IPv4: [Messages]  Recvd  = %10u | Sent = %10u", $aICMPStats[0], $aICMPStats[2]) & @CRLF     $sSplashText &= StringFormat("IPv6: [Messages]  Recvd  = %10u | Sent = %10u", $aICMPv6Stats[0], $aICMPv6Stats[2]) & @CRLF     For $i = 0 To $nInterfaces - 1 ;~         $aNIEntryInfo = _Network_InterfaceEntryInfo($aIPv4AddrTable[$i][0]) ;~         $sSplashText &= @CRLF & StringFormat("%35s", "== IP " & $aIPv4AddrTable[$i][1] & " ==" ) & @CRLF         $aNIEntryInfo = _Network_InterfaceEntryInfo($aIPAllAddrTable[$i][0])         If @error Then             ConsoleWrite("_Network_InterfaceEntryInfo return, @error = " & @error & ", @extended = " & @extended & @CRLF)             ExitLoop         EndIf         If $aIPAllAddrTable[$i][11] <> "" Then             $sSplashText &= @CRLF & StringFormat("%40s", "== IPv4 " & $aIPAllAddrTable[$i][11] & " ==" ) & @CRLF         Else             $sSplashText &= @CRLF & StringFormat("%52s", "== IPv6 " & $aIPAllAddrTable[$i][12] & " ==" ) & @CRLF         EndIf         $sSplashText &= StringFormat("%45.56s", $aNIEntryInfo[6]) & @CRLF         ; Octet *should* be the same as Bytes..         $sSplashText &= StringFormat("Data (Octets/Bytes): Recvd = %10u | Sent = %10u", $aNIEntryInfo[10], $aNIEntryInfo[16]) & @CRLF         $sSplashText &= StringFormat("Unicast Packets:     Recvd = %10u | Sent = %10u", $aNIEntryInfo[11], $aNIEntryInfo[17]) & @CRLF         $sSplashText &= StringFormat("Non-Unicast Packets: Recvd = %10u | Sent = %10u", $aNIEntryInfo[12], $aNIEntryInfo[18]) & @CRLF     Next     $sSplashText &= @CRLF & StringFormat("%35s", "[ESC] Exits") & @CRLF     ControlSetText($hSplash, "", "[CLASS:Static; INSTANCE:1]", $sSplashText)     Sleep(500) Until $bHotKeyPressed NetworkStatistics.zip ~prev version. downloads: >100
      Updates:
      2013-07-11:
       Changed: _Network_IPv4AdaptersInfoEx() now returns all IP's (if requested) and Address Masks
       Fixed: WSALastError call possible crash with non-array variable
       Changed: _Network_IPAllAddressTable() now allows 'down' status interfaces to be returned
       Added: Some comments on development, info on getting additional stats in the UDF
      2013-07-06:
       Added: Much more Adapter Information
       Changed: Example is now separate from the UDF
       Fixed some minor issues here and there
       Changed: Global Handle to IPHLPAPI.DLL is now contained in the UDF and used to speed up function calls
       Misc. Other fixes I didn't keep track of!
      2013-07-02:
       Hotfix: Ipv6 indexing error
       Fixed: indexing, updated and enhanced output
       Changed: Various functions return arrays even if failure - this is to make XP pre-SP1 and also collection of IPv6 less troublesome. @error should still be checked on return though!
       Added: Adapter and Interface information and statistics collection
      2013-06-20:
       Now covers all the 'p's - IP and ICMP now added