Jump to content
jerrbert

Memory Leak

Recommended Posts

jerrbert

I need to find the version number for the firmware of a USB mic on remote machines.  The script below does the trick nicely except for eating up more and more RAM on the machine I'm running the script on.  Consistently, when running this script against 100 machines, I can watch the RAM usage go from 14MB to almost 3GB.  Since memory usage is above 90% by the time it gets through with 100 machines, I have to run the script in batches (there are 825 total in this market).

I have been hunting for a solution through these forums (and others) unsuccessfully, so I figured I would ask to see how I can improve the script to use significantly less memory.  i have tried clearing variables and arrays after use, but I'm either doing it wrong, or it's not helping.

Any help you can offer would be awesome.  Thanks!!

;Include
#RequireAdmin
#include <array.au3>
#include <File.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Excel.au3>
#include <GuiListBox.au3>
#include <Date.au3>
#include <ProgressConstants.au3>

;Variables
Local $logExists, $logOpen, $File, $excelOpen, $FileOpen, $MICsNum, $MICsRecords, $colItems, $versionOS, $pcName
Local $objWMIService, $objItem, $sysDate, $logDate, $progress, $MICRange, $i, $n, $y, $x, $noPing, $Ping, $DeletePing, $pingProgress, $vSearch, $extended
Local $fileArray, $dragonLogPath, $firmwareFile, $firmLoc, $firmExtLong, $firmExt, $xCompCell, $xVersCell
Local $fmicLog = "C:\FMICLog.txt"
Local $DeletePing[1]
Local $wbemFlagReturnImmediately = 0x10
Local $wbemFlagForwardOnly = 0x20




#Region ### START Koda GUI section ### Form=c:\scripts\blankprogressbar.kxf
Local $BlankProgressBar = GUICreate("PowerMIC II Firmware Check", 522, 73, 192, 124)
Local $progressBar = GUICtrlCreateProgress(8, 8, 502, 33)
Local $barLabel = GUICtrlCreateLabel("Performing opening tasks...", 8, 48, 502, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Do
    ;Check for Dragon Log
    ;If it doesn't exist, create it
    $logExists = FileExists($fmicLog)
    If $logExists = 0 Then
        _FileCreate($fmicLog)
    EndIf
    GUICtrlSetData($progressBar, 20)

    $logOpen = FileOpen($fmicLog, 1)
    FileWrite($logOpen, "Script started." & @CRLF)
    GUICtrlSetData($progressBar, 40)

    ;Open Excel Spreadsheet to gather names of the PCs to check for powermic firmware version
    $File = "C:\Scripts\DragonMICsACH.xlsx"
    $excelOpen = _Excel_Open(False)
    $FileOpen = _Excel_BookOpen($excelOpen, $File)

    $MICsNum = _Excel_RangeRead($FileOpen, "Workstations", "B1")
    FileWrite($logOpen, "Number of workstations:  " & $MICsNum & @CRLF)
    GUICtrlSetData($progressBar, 60)

    $MICRange = "A1:A" & $MICsNum
    FileWrite($logOpen, "Spreadsheet Range:  " & $MICRange & @CRLF)
    GUICtrlSetData($progressBar, 80)

    $MICsRecords = _Excel_RangeRead($FileOpen, "Workstations", $MICRange)
    GUICtrlSetData($progressBar, 100)
Until GUICtrlRead($progressBar) = 100
GUIDelete($BlankProgressBar)
Sleep(1000)


#Region ### START Koda GUI section ### Form=c:\scripts\blankprogressbar.kxf
$BlankProgressBar = GUICreate("PowerMIC II Firmware Check", 522, 73, 192, 124)
$progressBar = GUICtrlCreateProgress(8, 8, 502, 33)
GUICtrlSetColor(-1, 0x008000)
$barLabel = GUICtrlCreateLabel("Pinging workstations...", 8, 48, 502, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Do
    $noPing = 0
    ;Set the number of workstations to be pinged
    For $i = 0 To UBound($MICsRecords) - 1
        ;Ping workstation
        GUICtrlSetData($barLabel, "Pinging " & $MICsRecords[$i])
        $Ping = Ping($MICsRecords[$i])

        ;Create another array of workstations that we could not ping
        ;We are going to remove them from the original array
        If $Ping = 0 Then
            FileWrite($logOpen, $MICsRecords[$i] & "  Could not be pinged." & @CRLF)
            $noPing = $noPing + 1
            _ArrayAdd($DeletePing, $MICsRecords[$i])
        EndIf

        ;Set progress based on the percentage of workstations completed
        GUICtrlSetData($progressBar, $i/(UBound($MICsRecords) - 1) * 100)
    Next
Until GUICtrlRead($progressBar) = 100
GUIDelete($BlankProgressBar)
Sleep(1000)

;Display a message box telling the user which PCs that could not be pinged
For $i = 1 To UBound($DeletePing) - 1
    $vSearch = _ArraySearch($MICsRecords, $DeletePing[$i])
    _ArrayDelete($MICsRecords, $vSearch)
Next

;Clearing array to clear memory (hopefully)
Local $DeletePing[1]

If $noPing > 0 Then
    FileWrite($logOpen, $noPing & " workstations that could not be pinged were removed from the array." & @CRLF)
EndIf


#Region ### START Koda GUI section ### Form=c:\scripts\blankprogressbar.kxf
$BlankProgressBar = GUICreate("PowerMIC II Firmware Check", 522, 73, 192, 124)
$progressBar = GUICtrlCreateProgress(8, 8, 502, 33)
GUICtrlSetColor(-1, 0x000080)
$barLabel = GUICtrlCreateLabel("Checking workstations...", 8, 48, 502, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

;check for version - loop through PC list and check each one
Do
    For $x = 0 To UBound($MICsRecords) - 1
        Local $fileNum = 0
        $xCompCell = "A" & $x + 827
        $xVersCell = "B" & $x + 827
        GUICtrlSetData($barLabel, "Checking " & $MICsRecords[$x] & " version.")
        ;make sure that the variables used in each iteration is cleared before the new iteration starts
        $colItems = ""
        $versionOS = ""
        $pcName = ""

        $pcName = $MICsRecords[$x]

        ;Connect to the WMI database on the selected PC
        ;We just need to collect the Operating System info
        $objWMIService = ObjGet("winmgmts:\\" & $pcName & "\root\CIMV2")
        ;Check to make sure that the connection was good.
        If Not IsObj($objWMIService) Then
            ;Log that we were unable to connect to the device
            FileWrite($logOpen, $pcName & "  Unable to connect." & @CRLF)
        Else
            ;Since the connection was good, gather the OS
            $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

            ;Again, check to make sure the collection was successful, then save the info
            If IsObj($colItems) then
                For $objItem In $colItems
                    $versionOS = $objItem.Caption
                Next
                ;Log the fact that the version was gathered
                FileWrite($logOpen, $pcName & "  OS:  " & $versionOS & @CRLF)
            Else
                ;log the fact that the script could not make a connection
                ;to the machine, even though it could ping.
                FileWrite($logOpen, $pcName & "  Failed to connect to gather OS version and RAM." & @CRLF)
            Endif
        EndIf

        If StringInStr($versionOS, "windows 7") > 0 Then
            GUICtrlSetData($barLabel, "WIN7:  Checking PowerMIC II version on " & $MICsRecords[$x])
            ;Check the version of the powermic firmware/driver

            $fileArray =_FileListToArrayRec("\\" & $pcName & "\C$\Users\", "*", 8, 1, 0, 2)
            If @error Then
                $extended = @extended
                If $extended = 1 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Path not found or invalid." & @CRLF)
                ElseIf $extended = 2 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Include parameter." & @CRLF)
                ElseIf $extended = 3 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude parameter." & @CRLF)
                ElseIf $extended = 4 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude_Folders parameter." & @CRLF)
                ElseIf $extended = 5 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturn parameter." & @CRLF)
                ElseIf $extended = 6 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iRecur parameter." & @CRLF)
                ElseIf $extended = 7 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iSort parameter." & @CRLF)
                ElseIf $extended = 8 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturnPath parameter." & @CRLF)
                ElseIf $extended = 9 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - No files/folders found." & @CRLF)
                Else
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Error creating the array of file paths." & @CRLF)
                EndIf
            Else
                ;Check log file for the PowerMic II firmware version
                For $n = 1 To $fileArray[0]
                    If StringInStr($fileArray[$n], "dragon.log") > 0 Then
                        $dragonLogPath = $fileArray[$n]
                        $firmwareFile = FileReadToArray($dragonLogPath)
                        For $y = 0 to UBound($firmwareFile) - 1
                            If StringInStr($firmwareFile[$y], "firmware") > 0 Then
                                $fileNum = 1
                                $firmLoc = StringInStr($firmwareFile[$y], "firmware")
                                $firmExtLong = StringMid($firmwareFile[$y], $firmLoc, 21)
                                $firmExt = StringRight($firmExtLong, 3)
                                FileWrite($logOpen, $pcName & "  Firmware version: " & $firmExt & @CRLF)
                                $firmwareFile = 0
                                ExitLoop
                            EndIf
                        Next
                        If $fileNum = 1 Then
                            FileWrite($logOpen, $pcName & "  dragon.log path is:  " & $dragonLogPath & @CRLF)
                            ExitLoop
                        EndIf
                    EndIf
                Next
                $fileArray = 0
                If $fileNum = 0 Then
                    FileWrite($logOpen, $pcName & "  Unable to find the version number within any Dragon.log file." & @CRLF)
                EndIf
            EndIf

            ;write firmware version to excel spreadsheet
            _Excel_RangeWrite($FileOpen, "DataExtract", $pcName, $xCompCell)
            If @error Then
                Local $excelError = @error
                If $excelError = 1 Then
                    FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                ElseIf $excelError = 2 Then
                    FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 3 Then
                    FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 4 Then
                    FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                EndIf
            EndIf
            If $fileNum = 1 Then
                _Excel_RangeWrite($FileOpen, "DataExtract", $firmExt, $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            Else
                _Excel_RangeWrite($FileOpen, "DataExtract", "Unable to find version.", $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            EndIf


        ElseIf StringInStr($versionOS, "windows xp") > 0 Then
            GUICtrlSetData($barLabel, "WINXP:  Checking PowerMIC II version on " & $MICsRecords[$x])
            ;Check the version of the powermic firmware/driver

            $fileArray =_FileListToArrayRec("\\" & $pcName & "\C$\Documents and Settings\", "*", 8, 1, 0, 2)
            If @error Then
                $extended = @extended
                If $extended = 1 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Path not found or invalid." & @CRLF)
                ElseIf $extended = 2 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Include parameter." & @CRLF)
                ElseIf $extended = 3 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude parameter." & @CRLF)
                ElseIf $extended = 4 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude_Folders parameter." & @CRLF)
                ElseIf $extended = 5 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturn parameter." & @CRLF)
                ElseIf $extended = 6 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iRecur parameter." & @CRLF)
                ElseIf $extended = 7 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iSort parameter." & @CRLF)
                ElseIf $extended = 8 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturnPath parameter." & @CRLF)
                ElseIf $extended = 9 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - No files/folders found." & @CRLF)
                Else
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Error creating the array of file paths." & @CRLF)
                EndIf
            Else
                ;Check log file for the PowerMic II firmware version
                For $n = 1 To $fileArray[0]
                    If StringInStr($fileArray[$n], "dragon.log") > 0 Then
                        $dragonLogPath = $fileArray[$n]
                        $firmwareFile = FileReadToArray($dragonLogPath)
                        For $y = 0 to UBound($firmwareFile) - 1
                            If StringInStr($firmwareFile[$y], "firmware") > 0 Then
                                $fileNum = 1
                                $firmLoc = StringInStr($firmwareFile[$y], "firmware")
                                $firmExtLong = StringMid($firmwareFile[$y], $firmLoc, 21)
                                $firmLoc = ""
                                $firmExt = StringRight($firmExtLong, 3)
                                $firmExtLong = ""
                                FileWrite($logOpen, $pcName & "  " & $firmExt & @CRLF)
                                $firmwareFile = 0
                                ExitLoop
                            EndIf
                        Next
                        If $fileNum = 1 Then
                            FileWrite($logOpen, $pcName & "  dragon.log path is:  " & $dragonLogPath & @CRLF)
                            ExitLoop
                        EndIf
                    EndIf
                    $dragonLogPath = ""
                Next
                $fileArray = 0
                If $fileNum = 0 Then
                    FileWrite($logOpen, $pcName & "  Unable to find the version number within any Dragon.log file." & @CRLF)
                EndIf
            EndIf

            ;write firmware version to excel spreadsheet
            _Excel_RangeWrite($FileOpen, "DataExtract", $pcName, $xCompCell)
            If @error Then
                Local $excelError = @error
                If $excelError = 1 Then
                    FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                ElseIf $excelError = 2 Then
                    FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 3 Then
                    FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 4 Then
                    FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                EndIf
            EndIf
            If $fileNum = 1 Then
                _Excel_RangeWrite($FileOpen, "DataExtract", $firmExt, $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            Else
                _Excel_RangeWrite($FileOpen, "DataExtract", "Unable to find version.", $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            EndIf


        EndIf
        GUICtrlSetData($progressBar, $x/(UBound($MICsRecords)-1)*100)
        $pcName = ""
    Next
Until GUICtrlRead($progressBar) = 100
GUIDelete($BlankProgressBar)
Sleep(1000)

FileWrite($logOpen, "Script complete." & @CRLF & @CRLF & @CRLF)

;Close Excel spreadsheet
_Excel_BookClose($FileOpen, True)
_Excel_Close($excelOpen, Default, True)
FileClose($logOpen)

 

Share this post


Link to post
Share on other sites
kaisies

Check for dragon log is inside the loop. Move it above your do :) 

Share this post


Link to post
Share on other sites
JohnOne

For a start, you should not be opening a file inside a loop without also closing it.

$logOpen = FileOpen($fmicLog, 1)

Or an excel object

$FileOpen = _Excel_BookOpen($excelOpen, $File)

 

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
jerrbert

Check for dragon log is inside the loop. Move it above your do :) 

That particular Do...Until is only there to give me a visual that this section is being worked on.  I can probably remove the entire loop, as it only takes a second or two to complete and exit.

Share this post


Link to post
Share on other sites
jerrbert

For a start, you should not be opening a file inside a loop without also closing it.

 

Fair enough.  That's two against that loop.  I will remove that loop, as it's only there to facilitate the progress bar and because it runs through that section so quickly (a second or two), it's not really needed.

Share this post


Link to post
Share on other sites
jerrbert

JohnOne, I have changed the opening of the script from this:

#Region ### START Koda GUI section ### Form=c:\scripts\blankprogressbar.kxf
Local $BlankProgressBar = GUICreate("PowerMIC II Firmware Check", 522, 73, 192, 124)
Local $progressBar = GUICtrlCreateProgress(8, 8, 502, 33)
Local $barLabel = GUICtrlCreateLabel("Performing opening tasks...", 8, 48, 502, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Do
    ;Check for Dragon Log
    ;If it doesn't exist, create it
    $logExists = FileExists($fmicLog)
    If $logExists = 0 Then
        _FileCreate($fmicLog)
    EndIf
    GUICtrlSetData($progressBar, 20)

    $logOpen = FileOpen($fmicLog, 1)
    FileWrite($logOpen, "Script started." & @CRLF)
    GUICtrlSetData($progressBar, 40)

    ;Open Excel Spreadsheet to gather names of the PCs to check for powermic firmware version
    $File = "C:\Scripts\DragonMICsACH.xlsx"
    $excelOpen = _Excel_Open(False)
    $FileOpen = _Excel_BookOpen($excelOpen, $File)

    $MICsNum = _Excel_RangeRead($FileOpen, "Workstations", "B1")
    FileWrite($logOpen, "Number of workstations:  " & $MICsNum & @CRLF)
    GUICtrlSetData($progressBar, 60)

    $MICRange = "A1:A" & $MICsNum
    FileWrite($logOpen, "Spreadsheet Range:  " & $MICRange & @CRLF)
    GUICtrlSetData($progressBar, 80)

    $MICsRecords = _Excel_RangeRead($FileOpen, "Workstations", $MICRange)
    GUICtrlSetData($progressBar, 100)
Until GUICtrlRead($progressBar) = 100
GUIDelete($BlankProgressBar)
Sleep(1000)

to this:

;Check for Dragon Log
;If it doesn't exist, create it
$logExists = FileExists($fmicLog)
If $logExists = 0 Then
    _FileCreate($fmicLog)
EndIf

$logOpen = FileOpen($fmicLog, 1)
FileWrite($logOpen, "Script started." & @CRLF)

;Open Excel Spreadsheet to gather names of the PCs to check for powermic firmware version
$File = "C:\Scripts\DragonMICsACH.xlsx"
$excelOpen = _Excel_Open(False)
$FileOpen = _Excel_BookOpen($excelOpen, $File)

$MICsNum = _Excel_RangeRead($FileOpen, "Workstations", "B1")
FileWrite($logOpen, "Number of workstations:  " & $MICsNum & @CRLF)

$MICRange = "A1:A" & $MICsNum
FileWrite($logOpen, "Spreadsheet Range:  " & $MICRange & @CRLF)

$MICsRecords = _Excel_RangeRead($FileOpen, "Workstations", $MICRange)

That removes those pieces out of a loop.  I will be testing that as soon as I get done with this update.

 

As for the Local DeletePing[1] - the documentation in the help file says that if I re-declare an array, it will clear the array.  This was another attempt to reduce the memory usage.  Is this not the case?  Is there a better way, or does clearing the array not have an affect on memory usage?

Share this post


Link to post
Share on other sites
jerrbert

I did the test.  It hit 8 PCs.  Memory usage went from 14MB to approx. 170MB, equaling an increase of about 20MB per machine.  This is consistent with previous runs.

I found the following in the help file under Dim/Global/Local/Const:

Declaring the same variable name again will erase all array values and reset the dimensions to the new definition.

 

Share this post


Link to post
Share on other sites
JohnOne

I see, then it's fit for your use, but at the tiny expense of a minute bit of performance.

I know nothing of _FileListToArrayRec but I see you set recursion and it looks to be used quite a lot, so I'd look into that next if I were you.

Are you looping through GBs of folder paths?

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
jerrbert

I am looping through an enormous number of file and folder paths.  There is a separate Dragon.log file for each user that has logged into any given machine.  The path is the same for each user, but I have no way of knowing which users have previously logged into any given machine.  Also, a user may have the Dragon.log file, but for some reason, the firmware is not listed in the log file.  I have the script set up to look for another Dragon.log file if that is the case.

For instance, my user name on the network is 69310, so the path to the Dragon.log file (on a WIN7 box) is:

\\AJ21\C$\Users\69310\AppData\Roaming\Nuance\NaturallySpeaking12\Dragon.log

To get to that, I set up the _FileListToArrayRec to grab everything in the Users folder, subfolders and files, as well.  That's a great point.  Let me consider this and see if I can't make this look through fewer files.

After that, I am reading a TXT file to an array and looping through it to find the line that lists out the firmware version.  I looked at one of the files and it is 86KB, translating to just under 1000 lines.  Not sure how to make that smaller.  Maybe if I read 30-50 lines at a time, only checking more if the version is not found.

Hopefully, I will be able to make the changes shortly and let you know how it went.  Thanks!

Share this post


Link to post
Share on other sites
JohnOne

Just as a sanity check, consider where you use _FileListToArrayRec and where the resulting array is used.

It seems you only release its memory if the array actually gets used in an if else block.

So try...

Do
    For $x = 0 To UBound($MICsRecords) - 1
        Local $fileNum = 0
        $xCompCell = "A" & $x + 827
        $xVersCell = "B" & $x + 827
        GUICtrlSetData($barLabel, "Checking " & $MICsRecords[$x] & " version.")
        ;make sure that the variables used in each iteration is cleared before the new iteration starts
        $colItems = ""
        $versionOS = ""
        $pcName = ""

        $pcName = $MICsRecords[$x]

        ;Connect to the WMI database on the selected PC
        ;We just need to collect the Operating System info
        $objWMIService = ObjGet("winmgmts:\\" & $pcName & "\root\CIMV2")
        ;Check to make sure that the connection was good.
        If Not IsObj($objWMIService) Then
            ;Log that we were unable to connect to the device
            FileWrite($logOpen, $pcName & "  Unable to connect." & @CRLF)
        Else
            ;Since the connection was good, gather the OS
            $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

            ;Again, check to make sure the collection was successful, then save the info
            If IsObj($colItems) then
                For $objItem In $colItems
                    $versionOS = $objItem.Caption
                Next
                ;Log the fact that the version was gathered
                FileWrite($logOpen, $pcName & "  OS:  " & $versionOS & @CRLF)
            Else
                ;log the fact that the script could not make a connection
                ;to the machine, even though it could ping.
                FileWrite($logOpen, $pcName & "  Failed to connect to gather OS version and RAM." & @CRLF)
            Endif
        EndIf

        If StringInStr($versionOS, "windows 7") > 0 Then
            GUICtrlSetData($barLabel, "WIN7:  Checking PowerMIC II version on " & $MICsRecords[$x])
            ;Check the version of the powermic firmware/driver

            $fileArray =_FileListToArrayRec("\\" & $pcName & "\C$\Users\", "*", 8, 1, 0, 2)
            If @error Then
                $extended = @extended
                If $extended = 1 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Path not found or invalid." & @CRLF)
                ElseIf $extended = 2 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Include parameter." & @CRLF)
                ElseIf $extended = 3 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude parameter." & @CRLF)
                ElseIf $extended = 4 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude_Folders parameter." & @CRLF)
                ElseIf $extended = 5 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturn parameter." & @CRLF)
                ElseIf $extended = 6 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iRecur parameter." & @CRLF)
                ElseIf $extended = 7 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iSort parameter." & @CRLF)
                ElseIf $extended = 8 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturnPath parameter." & @CRLF)
                ElseIf $extended = 9 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - No files/folders found." & @CRLF)
                Else
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Error creating the array of file paths." & @CRLF)
                EndIf
                $fileArray = 0 ; <############################################################################################
            Else
                ;Check log file for the PowerMic II firmware version
                For $n = 1 To $fileArray[0]
                    If StringInStr($fileArray[$n], "dragon.log") > 0 Then
                        $dragonLogPath = $fileArray[$n]
                        $firmwareFile = FileReadToArray($dragonLogPath)
                        For $y = 0 to UBound($firmwareFile) - 1
                            If StringInStr($firmwareFile[$y], "firmware") > 0 Then
                                $fileNum = 1
                                $firmLoc = StringInStr($firmwareFile[$y], "firmware")
                                $firmExtLong = StringMid($firmwareFile[$y], $firmLoc, 21)
                                $firmExt = StringRight($firmExtLong, 3)
                                FileWrite($logOpen, $pcName & "  Firmware version: " & $firmExt & @CRLF)
                                $firmwareFile = 0
                                ExitLoop
                            EndIf
                        Next
                        If $fileNum = 1 Then
                            FileWrite($logOpen, $pcName & "  dragon.log path is:  " & $dragonLogPath & @CRLF)
                            ExitLoop
                        EndIf
                    EndIf
                Next
                $fileArray = 0
                If $fileNum = 0 Then
                    FileWrite($logOpen, $pcName & "  Unable to find the version number within any Dragon.log file." & @CRLF)
                EndIf
            EndIf

            ;write firmware version to excel spreadsheet
            _Excel_RangeWrite($FileOpen, "DataExtract", $pcName, $xCompCell)
            If @error Then
                Local $excelError = @error
                If $excelError = 1 Then
                    FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                ElseIf $excelError = 2 Then
                    FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 3 Then
                    FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 4 Then
                    FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                EndIf
            EndIf
            If $fileNum = 1 Then
                _Excel_RangeWrite($FileOpen, "DataExtract", $firmExt, $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            Else
                _Excel_RangeWrite($FileOpen, "DataExtract", "Unable to find version.", $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            EndIf


        ElseIf StringInStr($versionOS, "windows xp") > 0 Then
            GUICtrlSetData($barLabel, "WINXP:  Checking PowerMIC II version on " & $MICsRecords[$x])
            ;Check the version of the powermic firmware/driver

            $fileArray =_FileListToArrayRec("\\" & $pcName & "\C$\Documents and Settings\", "*", 8, 1, 0, 2)
            If @error Then
                $extended = @extended
                If $extended = 1 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Path not found or invalid." & @CRLF)
                ElseIf $extended = 2 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Include parameter." & @CRLF)
                ElseIf $extended = 3 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude parameter." & @CRLF)
                ElseIf $extended = 4 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid Exclude_Folders parameter." & @CRLF)
                ElseIf $extended = 5 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturn parameter." & @CRLF)
                ElseIf $extended = 6 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iRecur parameter." & @CRLF)
                ElseIf $extended = 7 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iSort parameter." & @CRLF)
                ElseIf $extended = 8 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Invalid $iReturnPath parameter." & @CRLF)
                ElseIf $extended = 9 Then
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - No files/folders found." & @CRLF)
                Else
                    FileWrite($logOpen, $pcName & "  FileListToArray Error - Error creating the array of file paths." & @CRLF)
                EndIf
                $fileArray = 0 ; <############################################################################################
            Else
                ;Check log file for the PowerMic II firmware version
                For $n = 1 To $fileArray[0]
                    If StringInStr($fileArray[$n], "dragon.log") > 0 Then
                        $dragonLogPath = $fileArray[$n]
                        $firmwareFile = FileReadToArray($dragonLogPath)
                        For $y = 0 to UBound($firmwareFile) - 1
                            If StringInStr($firmwareFile[$y], "firmware") > 0 Then
                                $fileNum = 1
                                $firmLoc = StringInStr($firmwareFile[$y], "firmware")
                                $firmExtLong = StringMid($firmwareFile[$y], $firmLoc, 21)
                                $firmLoc = ""
                                $firmExt = StringRight($firmExtLong, 3)
                                $firmExtLong = ""
                                FileWrite($logOpen, $pcName & "  " & $firmExt & @CRLF)
                                $firmwareFile = 0
                                ExitLoop
                            EndIf
                        Next
                        If $fileNum = 1 Then
                            FileWrite($logOpen, $pcName & "  dragon.log path is:  " & $dragonLogPath & @CRLF)
                            ExitLoop
                        EndIf
                    EndIf
                    $dragonLogPath = ""
                Next
                $fileArray = 0
                If $fileNum = 0 Then
                    FileWrite($logOpen, $pcName & "  Unable to find the version number within any Dragon.log file." & @CRLF)
                EndIf
            EndIf

            ;write firmware version to excel spreadsheet
            _Excel_RangeWrite($FileOpen, "DataExtract", $pcName, $xCompCell)
            If @error Then
                Local $excelError = @error
                If $excelError = 1 Then
                    FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                ElseIf $excelError = 2 Then
                    FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 3 Then
                    FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                ElseIf $excelError = 4 Then
                    FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                    If @extended Then
                        FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                    EndIf
                EndIf
            EndIf
            If $fileNum = 1 Then
                _Excel_RangeWrite($FileOpen, "DataExtract", $firmExt, $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            Else
                _Excel_RangeWrite($FileOpen, "DataExtract", "Unable to find version.", $xVersCell)
                If @error Then
                    Local $excelError = @error
                    If $excelError = 1 Then
                        FileWrite($logOpen, "ERROR: Workbook is not an object or not a workbook object." & @CRLF)
                    ElseIf $excelError = 2 Then
                        FileWrite($logOpen, "ERROR: Worksheet name or index are invalid or worksheet is not a worksheet object." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 3 Then
                        FileWrite($logOpen, "ERROR: Range is invalid." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    ElseIf $excelError = 4 Then
                        FileWrite($logOpen, "ERROR: Error occurred when writing data." & @CRLF)
                        If @extended Then
                            FileWrite($logOpen, "ERROR: COM code:  " & @extended & @CRLF)
                        EndIf
                    EndIf
                EndIf
            EndIf


        EndIf
        GUICtrlSetData($progressBar, $x/(UBound($MICsRecords)-1)*100)
        $pcName = ""
    Next
Until GUICtrlRead($progressBar) = 100

 


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
clicked

I think the memory leak is in the WMI object. I believe this is a known bug you can google up. I see you are connecting to an array of computers, I would store the WMI handles in an array and ObjGet them once only.

Share this post


Link to post
Share on other sites
clicked

There is this:

https://support.microsoft.com/en-us/kb/977357

and there may be other issues with it. I used WMI inside a 1 second loop to get CPU usage, and ended up with gigabytes of private memory. It took me a long time to suspect WMI, but simply moving the ObjGet outside the loop fixed the problem. You can put a WMI ObjGet inside a tight loop yourself, as a test, and watch the memory run up.

Edited by clicked
  • Like 1

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

×