Sign in to follow this  
Followers 0
pl123

Array won't save to file

6 posts in this topic

I'm making a script that will list all the run at startup programs on your computer in an array, and then save it to a file, based on Danny35d's script for listing installed programs at http://www.autoitscript.com/forum/index.php?showtopic=18034

This is what I have so far:

#include <Array.au3>
#include <File.au3>
#include <WindowsConstants.au3>

Global Const $RunAtStartupRegKey =  "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
Global $MonthName, $DayName

_DetermineMonthName ()
_DetermineDayName ()

Dim $RunAtStartupArray[1]

$SaveAs = FileSaveDialog ("Select folder for output of list of programs that run at startup", "Desktop", "Text files (*.txt)", 16, "RunAtStartup.txt" )
$RunAtStartup = _RunAtStartup ()
_ArraySort ($RunAtStartup, 0, 1)
ReDim $RunAtStartup [UBound($RunAtStartup)]
ReDim $RunAtStartup [UBound($RunAtStartup)]
_ArrayAdd ($RunAtStartup, "-----------------------------------------------------")
_ArrayAdd ($RunAtStartup, "This list was created on " & $DayName & ", " & $MonthName & " " & @MDAY & ", " & @YEAR & " at " & @HOUR & ":" & @MIN & ":" & @SEC & ":" & @MSEC)
_FileWriteFromArray ($SaveAs, $RunAtStartup)

Func _DetermineMonthName ()
    Select
        Case @MON = 01
            $MonthName = "January"
        Case @MON = 02
            $MonthName = "February"
        Case @MON = 03
            $MonthName = "March"
        Case @MON = 04
            $MonthName = "April"
        Case @MON = 05
            $MonthName = "May"
        Case @MON = 06
            $MonthName = "June"
        Case @MON = 07
            $MonthName = "July"
        Case @MON = 08
            $MonthName = "August"
        Case @MON = 09
            $MonthName = "September"
        Case @MON = 10
            $MonthName = "October"
        Case @MON = 11
            $MonthName = "November"
        Case @MON = 12
            $MonthName = "December"
    EndSelect
EndFunc

Func _DetermineDayName ()
    Select
        Case @WDAY = 1
            $DayName = "Sunday"
        Case @WDAY = 02
            $DayName = "Monday"
        Case @WDAY = 03
            $DayName = "Tuesday"
        Case @WDAY = 04
            $DayName = "Wednesday"
        Case @WDAY = 05
            $DayName = "Thursday"
        Case @WDAY = 06
            $DayName = "Friday"
        Case @WDAY = 07
            $DayName = "Saturday"
    EndSelect
EndFunc

Func _RunAtStartup ()
    Local $NumberOfKeys = 1
    While 1
        $Key = RegEnumKey ($RunAtStartupRegKey, $NumberOfKeys)
        $Line = RegRead ($RunAtStartupRegKey & '\' & $Key, 'Displayname')
        If Not $Line = "" Then
            If Not IsDeclared ('RunAtStartupArray') Then Dim $RunAtStartupArray[1]
            ReDim $RunAtStartupArray[UBound($RunAtStartupArray) + 1]
            $RunAtStartupArray[0] = UBound($RunAtStartupArray) - 1
            $RunAtStartupArray[UBound($RunAtStartupArray) - 1] = $Line
        EndIf
        $NumberOfKeys = $NumberOfKeys + 1
    WEnd
    Select
        Case IsDeclared('RunAtStartupArray') = 0
            SetError (1)
            Return ('')
        Case IsDeclared('RunAtStartupArray') = 1
            SetError (0)
            Return($RunAtStartupArray)
    EndSelect
EndFunc

And also, how can I make a array that saves the name of a program, the version number, and the developer to a file?

Thanks for your help!

Share this post


Link to post
Share on other sites



maybe the never ending while statement in the function?


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I got it (the never ending while statement) fixed; thanks to iamtheky.

I placed

If Not @error = 0 then ExitLoop
in between these two lines of code.

$Key = RegEnumKey ($RunAtStartupRegKey, $NumberOfKeys)
If Not @error = 0 then ExitLoop
$Line = RegRead ($RunAtStartupRegKey & '\' & $Key, 'Displayname')

But now, when it saves, it gives me a blank file with the timestamp only. Is there anything else wrong?

_DetermineMonthName ()
_DetermineDayName ()

Dim $RunAtStartupArray[1]

$SaveAs = FileSaveDialog ("Select folder for output of list of programs that run at startup", "Desktop", "Text files (*.txt)", 16, "RunAtStartup.txt" )
$RunAtStartup = _RunAtStartup ()
_ArraySort ($RunAtStartup, 0, 1)
ReDim $RunAtStartup [UBound($RunAtStartup)]
ReDim $RunAtStartup [UBound($RunAtStartup)]
_ArrayAdd ($RunAtStartup, "-----------------------------------------------------")
_ArrayAdd ($RunAtStartup, "This list was created on " & $DayName & ", " & $MonthName & " " & @MDAY & ", " & @YEAR & " at " & @HOUR & ":" & @MIN & ":" & @SEC & ":" & @MSEC)
_FileWriteFromArray ($SaveAs, $RunAtStartup)

$StartupPrgmListingDone = MsgBox (65, "Startup Programs List - Completed", "Your programs have been successfully listed." & @CRLF & "To continue to the next part (file listing), click OK to continue." & @CRLF & "Click Cancel to quit.")
Select
    Case $StartupPrgmListingDone = 6
        _DoNothing ()
    Case $StartupPrgmListingDone = 7
        Exit
EndSelect

Func _RunAtStartup ()
    Local $NumberOfKeys = 1
    While 1
        $Key = RegEnumKey ($RunAtStartupRegKey, $NumberOfKeys)
    If Not @error = 0 then ExitLoop
        $Line = RegRead ($RunAtStartupRegKey & '\' & $Key, 'Displayname')
        If Not $Line = "" Then
            If Not IsDeclared ('RunAtStartupArray') Then Dim $RunAtStartupArray[1]
            ReDim $RunAtStartupArray[UBound($RunAtStartupArray) + 1]
            $RunAtStartupArray[0] = UBound($RunAtStartupArray) - 1
            $RunAtStartupArray[UBound($RunAtStartupArray) - 1] = $Line
        EndIf
        $NumberOfKeys = $NumberOfKeys + 1
    WEnd
    Select
        Case IsDeclared('RunAtStartupArray') = 0
            SetError (1)
            Return ('')
        Case IsDeclared('RunAtStartupArray') = 1
            SetError (0)
            Return($RunAtStartupArray)
    EndSelect
EndFunc

Other functions are in the first post.

Edited by pl123

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I cannot say what is exactly wrong in your example because it is not complete. I assume your array is empty.

Anyway, try this:

#Include <File.au3>
#include <Array.au3>
$delimiter = ";"
$file = "Test.csv"
$hFile = FileOpen($file, 2)
FileWriteLine($hFile, "Application" & $delimiter & "Path" & $delimiter & "Reg Type")
FileClose($hFile)
$aRun = RunKey()
;~ _FileWriteFromArray($file, $aRun) ;_FileWriteFromArray() is crashing for this array probably because of 2D array :-(
Array2CSV($file, $aRun) ;alternative for _FileWriteFromArray()
_ArrayDisplay($aRun)
Exit

Func RunKey() ;coded by UEZ
    Local $HKLM, $BaseKey
    Local $key_value, $key_description
    Local $run[1][3]
    $HKLM = 0x80000002
    $BaseKey = "Software\Microsoft\Windows\CurrentVersion\Run\"
    $i = 1
    $j = 0
    While 1
        $key_value = RegEnumVal("HKLM\" & $BaseKey, $i)
        If @error <> 0 Then ExitLoop
        If $key_value <> "" Then
            $key_description = RegRead("HKLM\" & $BaseKey, $key_value)
            $run[$j][0] = $key_value
            $run[$j][1] = $key_description
            $run[$j][2] = @extended ;REG_SZ(1), REG_EXPAND_SZ(2), REG_BINARY(3), REG_DWORD(4), REG_MULTI_SZ(7), REG_QWORD(11)
            ReDim $run[$j + 2][3]
            $j += 1
        EndIf
        $i += 1
    WEnd
    ReDim $run[UBound($run) - 1][4]
    _ArraySort($run)
    Return $run
EndFunc   ;==>Software

Func Array2CSV($file, $array, $start = 2, $delimiter = ";") ;2D array to file coded by UEZ
    Local $i, $j, $line
    For $i = 0 To UBound($array) - 1
        For $j = 0 To UBound($array, 2) - 1
            $line &= $array[$i][$j] & $delimiter
        Next
        $line = StringLeft($line, StringLen($line) - 1)
        _FileWriteToLine($file, $i + $start, $line)
        $line = ""
    Next
EndFunc

X64 run key check not implemented.

I hope it is helpful for you.

Br,

UEZ

PS:

The original _FileWriteFromArray() will crash because it can handle only 1D arrays:

Here the modified version for up to 2D arrays which should work:

; #FUNCTION# ====================================================================================================================
; Name...........: _FileWriteFromArray
; Description ...: Writes Array records to the specified file.
; Syntax.........: _FileWriteFromArray($File, $a_Array[, $i_Base = 0[, $i_UBound = 0]])
; Parameters ....: $File    - String path of the file to write to, or a file handle returned from FileOpen().
;                  $a_Array  - The array to be written to the file.
;                  $i_Base   - Optional: Start Array index to read, normally set to 0 or 1. Default=0
;                  $i_Ubound - Optional: Set to the last record you want to write to the File. default=0 - whole array.
; Return values .: Success - Returns a 1
;                  Failure - Returns a 0
;                  @Error  - 0 = No error.
;                  |1 = Error opening specified file
;                  |2 = Input is not an Array
;                  |3 = Error writing to file
; Author ........: Jos van der Zande <jdeb at autoitscript dot com>
; Modified.......: Updated for file handles by PsaltyDS at the AutoIt forums.
;                  Added 2D array support by UEZ
; Remarks .......: If a string path is provided, the file is overwritten and closed.
;                  To use other write modes, like append or Unicode formats, open the file with FileOpen() first and pass the file handle instead.
;                  If a file handle is passed, the file will still be open after writing.
; Related .......: _FileReadToArray
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _FileWriteFromArray($File, $a_Array, $i_Base = 0, $i_UBound = 0, $delim = ";")
    Local Const $FO_OVERWRITE   = 2 ; Write mode (erase previous contents)
    ; Check if we have a valid array as input
    If Not IsArray($a_Array) Then Return SetError(2, 0, 0)

    ; Check if array dimension is greater than 2
    If UBound($a_Array, 0) > 2 Then Return SetError(3, 0, 0)

    ; determine last entry
    Local $last = UBound($a_Array) - 1
    If $i_UBound < 1 Or $i_UBound > $last Then $i_UBound = $last
    If $i_Base < 0 Or $i_Base > $last Then $i_Base = 0

    ; Open output file for overwrite by default, or use input file handle if passed
    Local $hFile
    If IsString($File) Then
        $hFile = FileOpen($File, $FO_OVERWRITE)
    Else
        $hFile = $File
    EndIf
    If $hFile = -1 Then Return SetError(1, 0, 0)

    ; Write array data to file
    Local $ErrorSav = 0, $x, $y, $delimiter, $line
    Local $mArray = UBound($a_Array, 2) - 1
    If  $mArray > 0 Then $delimiter = $delim
    For $x = $i_Base To $i_UBound
        If $mArray > 0 Then
            For $y = 0 To $mArray
                $line &= $a_Array[$x][$y] & $delimiter
            Next
            $line = StringLeft($line, StringLen($line) - 1)
        Else
            $line = $a_Array[$x]
        EndIf
        If FileWrite($hFile, $line & @CRLF) = 0 Then
            $ErrorSav = 3
            ExitLoop
        EndIf
        $line = ""
    Next

    ; Close file only if specified by a string path
    If IsString($File) Then FileClose($hFile)

    ; Return results
    If $ErrorSav Then Return SetError($ErrorSav, 0, 0)
    Return 1
EndFunc   ;==>_FileWriteFromArray
Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Worked great! Thanks for this, the only issue I am having is that I need to append the array with 5 different arrays into a text file. But when I call this script a second time, it overwrites what was previously placed, is there an easy way to solve this? I guess worst case scenario I can make loop to reindex the array

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