Sign in to follow this  
Followers 0
LWC

FileRead works on Autorun.inf while Ini functions sometimes don't

9 posts in this topic

#1 ·  Posted (edited)

I've made a program that relies on IniReadSectionNames. It reads (~3K) Autorun.inf files in the working folder and creates a GUI based on their contents.

I made sure to revert to a default GUI upon @error.

But someone (with Windows XP SP3 32-bit) reported to me he always gets the default menu.

I sent him a FileRead command instead and it works! So seemingly there's no access problem to AutoRun.inf.

In the following demo code, I always hit success, but he always ends up with semi-success:

Local $hIniLocation = "Autorun.inf"
    Local $aSections = IniReadSectionNames($hIniLocation)
    If @error Then
        $aSections = FileRead($hIniLocation)
        if @error then
            msgbox(48, "Double error", "Alternative access failed too due to:" & @crlf & @error & @crlf & @extended)
        else
            msgbox(0, "Semi-success", "IniReadSectionNames failed, but alternativaly this file contains:" & @crlf & @crlf & $aSections)
        endif
    else
        msgbox(0, "Success", "IniReadSectionNames worked!")
    endif

Why is that? Is there something further to check with him?

Autorun.inf

Edited by LWC
More general topic and tag

Share this post


Link to post
Share on other sites



#2 ·  Posted

The code runs nice on my XP SP3 32-bit and I get "success"
Maybe a problem of rights as .inf  are system files

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

It seems to be about Autorun.inf specifically. If I change my script to use autorun.ini or something_else.inf, then it works for him.

But if FileRead works on Autorun.inf itself, why doesn't IniReadSectionNames?

Can I check the relevant rights and/or pipe IniReadSectionNames through FileRead (without creating a temp file just so it won't be called Autorun.inf)?

Edited by LWC

Share this post


Link to post
Share on other sites

#4 ·  Posted

Checking the rights for this particular file on one particular PC could be not easy if trouble comes from antivirus policy etc
But if FileRead works you might provide an alternative way as a workaround

#include <Array.au3>
$txt = FileRead(@ScriptDir & "\Autorun.inf")
$sections = StringRegExp($txt, '^|(?m)^\s*\[([^\]]+)', 3)
$sections[0] = UBound($sections)-1
_ArrayDisplay($sections)

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

That's very smart and works perfectly, thanks!

I'll submit a bug report asking to use your code internally in IniReadSectionNames as a fallback (unless of course they'll fix it directly).

But...IniReadSection suffers from the same issue. Can you suggest a bypass for it too?

Edited by LWC

Share this post


Link to post
Share on other sites

#6 ·  Posted

1 hour ago, LWC said:

I'll submit a bug report

IMHO it's not a good idea as the problem certainly comes from some particular configuration on the user's PC
Workarounds exist for most Ini* funcs. How many of these funcs is your script using ?

Share this post


Link to post
Share on other sites

#7 ·  Posted

But why not give the Ini functions the same powers that ReadFile has?

I only need IniReadSection, if you have a bypass.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I assume that File/Ini funcs don't all work the same way. Question for developpers  :)

Here is a possible workaround for IniReadSection

#include <Array.au3>

$txt = FileRead(@ScriptDir & "\Autorun.inf")
$sections = StringRegExp($txt, '^|(?m)^\s*\[([^\]]+)', 3)
$sections[0] = UBound($sections)-1
;_ArrayDisplay($sections)

For $i = 1 To $sections[0]
   ; read content of section
   $content = StringRegExp($txt, '\Q' & $sections[$i] & ']\E\s+([^\[]+)', 1)
   If IsArray($content) Then 
       ; get key/value pairs
       $tmp = StringRegExp($content[0], '(?m)^([^\v;=]+)=([^;\v]*)\N*$', 3)
       If not IsArray($tmp) Then 
            Msgbox(0,"", "section " & $sections[$i] & " is empty")
            ContinueLoop
       EndIf
       ; format to 2D array
       $n = UBound($tmp)
       Local $aArray[$n/2+1][2]
       For $j = 0 To $n-1
            $aArray[Int($j/2)+1][Mod($j, 2)] = $tmp[$j]
       Next
       $aArray[0][0] = $n/2
      _ArrayDisplay($aArray, "section " & $sections[$i])
   Else
      Msgbox(0,"", "section " & $sections[$i] & " is empty")
   EndIf
Next

 

Edited by mikell

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

I used your first regexp, but then continued with some simpler code combined with ideas from here.

#include <Array.au3>

$txt = FileRead(@ScriptDir & "\Autorun.inf")
$aSections = StringRegExp($txt, '^|(?m)^\s*\[([^\]]+)', 3)
$aSections[0] = UBound($aSections)-1
;_ArrayDisplay($aSections)

    For $iCount = 1 To $aSections[0]
        if $filecontent="" then
            $aKV = IniReadSection($hIniLocation, $aSections[$iCount])
            If @error Then ; If empty section then ignore (treat as void)
                ContinueLoop
            endif
        else
            $value = StringRegExp($filecontent, "\Q" & $aSections[$iCount] & ']\E\s+([^\[]+)', 1)
            If not IsArray($value) Then ; If empty section then ignore (treat as void)
                ContinueLoop
            endif
            If StringInStr($value[0], @CRLF, 1, 1) Then
                $value = StringSplit(StringStripCR($value[0]), @LF)
            ElseIf StringInStr($value[0], @LF, 1, 1) Then
                $value = StringSplit($value[0], @LF)
            Else
                $value = StringSplit($value[0], @CR)
            EndIf
            local $aKV[1][2]
            For $xCount = 1 To $value[0]
                if $value[$xCount]="" or StringLeft($value[$xCount], 1)=";" then ContinueLoop
                ReDim $aKV[ubound($aKV)+1][ubound($aKV, 2)]
                $value_temp = StringSplit($value[$xCount], "=", 2)
                $aKV[ubound($aKV)-1][0] = $value_temp[0]
                $aKV[ubound($aKV)-1][1] = $value_temp[1]
                $aKV[0][0] += 1
            next
            if $aKV[0][0]="" then ContinueLoop
        EndIf
        _ArrayDisplay($aKV, $aSections[$iCount])
    Next

What do you think?

Edited by LWC

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

    • ercicttech
      By ercicttech
      Hello, all..

      My AutoIT is pretty terrible - but I get by with trawling here
      I came across an issue where i had to parse a large key in a large ini file, and found that I was victim of inireadsection's limit of "Only the first 32767 chars are read for legacy reasons."
       
      I've attempted to put together some terrible code that parses an ini section.
      It's absolutely nowhere near good, but I figured I'd put it here so that folk who know what they're doing can laugh at improve it.
      $Ini = @ScriptDir & "\bigini.ini" Dim $IniArray[0][2] $KeyName = "Person" $R = FileOpen($Ini, 0) $IniStr = FileRead($R) FileClose($R) $Start = StringInStr($iniStr, "[" & $KeyName & "]") If $Start = 0 then Msgbox(16, "Error", "String not found") Exit EndIf $Stop = StringInStr($IniStr, @CRLF & "[", 0, 1, ($Start + 1)) If $Stop = 0 then $Stop = StringLen($IniStr) EndIf $String = StringMid($IniStr, $Start, ($Stop - $Start)) $Split = StringSplit($String, @CRLF, 1) $KeyCount = 0 Dim $IniArray[65535][2] For $Loop = 1 to $Split[0] $Add = "Y" $Str = $Split[$Loop] $EQBreak = StringInStr($Str, "=") Select Case StringMid($Str, 1, 1) = ";" $Add = "N" Case $EQBreak = 0 $Add = "N" Case Else $Add = "Y" EndSelect If $Add = "Y" then $KeyCount = $KeyCount + 1 $Key = StringMid($Str, 1, ($EQBreak - 1)) $Val = StringMid($Str, ($EQBreak + 1)) $IniArray[$KeyCount][0] = $Key $IniArray[$KeyCount][1] = $Val EndIf Next Redim $IniArray[$KeyCount +1][2] ; Add the number of hits to 00 to match inireadsection $IniArray[0][0] = $KeyCount _ArrayDisplay($IniArray) ; Do stuff with the Array like you would inireadsection  
    • RC86
      By RC86
      Afternoon, I could very well be doing this wrong so feel free to totally advise otherwise - I'm wanting to use a GUI to first display a key from within an INI file, then secondly change the INI file by using a FileSelectFolder command but then I want to see the GUI change to reflect the change I've just made.
      #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124) $Input1 = GUICtrlCreateInput(Iniread(@WorkingDir & "\test.ini","Path","FilePath",""), 64, 80, 121, 21) $Button1 = GUICtrlCreateButton("Change", 200, 80, 75, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 $selectedFolder = FileSelectFolder("Select Log Path Directory",@WorkingDir,0) If NOT $selectedFolder = "" Then $newLogPath = IniWrite(@WorkingDir & "\test.ini","Path","FilePath",$selectedFolder) EndIf EndSwitch WEnd So 2 part question really: (1) Should I be using GUICtrlCreateInput to display my INI read from within the GUI? (2) How can I refresh the GUI to update that to read the new information I've just written to the GUI?
      Thanks!

    • wimhek
      By wimhek
      Is it possible , and how can I read and write txt files from Icloud (apple service) ?
      Let me try to explain my application.
      On my Ipad and Iphone I create txt files. On my windows computer it is possible to read and modify these files manually, by logging in on www.icloud.com.
      What I want to make is an auto-it script who reads the txt file and create an new txt file on www.icloud.com,  so I can acces these on my ipad and/or phone.
       
      Thank you.
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good morning community!
      I was working on a script which read the content of a .ini file to retrieve the file that has to open, and, based on the value of a second key stored in the .ini file, set the window on top, minimized or maximized...
      I did something like this, but seems to not work properly...
      Could anyone please tell me what I'm doing wrong?
      Thank you  
       
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile_x64=prova.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <AutoItConstants.au3> ;#include <WinAPIEx.au3> #include <Array.au3> Local $sFileConfigurazione = @ScriptDir & "\configurazione_exe.ini" If(FileExists($sFileConfigurazione)) Then Local $aSezioneIni = IniReadSection($sFileConfigurazione, "CONFIGURAZIONE_EXE") If @error Then MsgBox($MB_ICONERROR, "Errore!", "Errore durante l'apertura del file: " & @CRLF & $sFileConfigurazione & @CRLF & "Errore: " & @error) Else ; Lancio dell'applicativo indicato nel file di configurazione Local $iPID = ShellExecute($aSezioneIni[1][1]) Local $hWnd If($iPID <> 0) Then Local $aWinList = WinList() For $i = 1 To $aWinList[0][0] If(WinGetProcess($aWinList[$i][1] = $iPID)) Then $hWnd = $aWinList[$i][1] EndIf Next Switch($aSezioneIni[2][1]) Case $aSezioneIni[2][1] = "MIN" ToolTip("MIN", 0, 0) WinSetState($hWnd, WinGetTitle($hWnd), @SW_MINIMIZE) Case $aSezioneIni[2][1] = "MAX" ToolTip("MAX", 0, 0) WinSetState($hWnd, WinGetTitle($hWnd), @SW_MAXIMIZE) Case $aSezioneIni[2][1] = "TOP" ToolTip("TOP", 0, 0) WinSetOnTop($hWnd, WinGetTitle($hWnd), $WINDOWS_ONTOP) EndSwitch EndIf EndIf EndIf And the .ini file is like this:
       
      [CONFIGURAZIONE_EXE] PercorsoExe=Here goes the path and the .exe to execute ModalitaAperturaExe=Here goes one of the value below /* TOP Shows the windows on top */ /* MIN Shows the window minimized */ /* MAX Shows the window maximized */  
    • antmar904
      By antmar904
      Hi,
      I ran a remote program on 180 computers and logged the output to a log file with paexec.  I'm trying to parse through the log file to see which computers launched the program successfully and record the computer name but I'm not sure how to go about it. 
      I can successfully open the log file, read it but not sure how to start separating the data.
      I've attached the log file, basically every computer entry in the log file for a new computer starts with "Connecting to <computername>..." I was thinking about using that as the start and stop point for retrieving the end results.  Anything with a "returned 0" is a success, everything is a fail.
      Any help is much appreciated.
      testlogfile.txt