Jump to content
Sign in to follow this  
LWC

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

Recommended Posts

LWC

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
mikell

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
LWC

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
mikell

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
LWC

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
mikell
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
LWC

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
mikell

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
LWC

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  

  • Similar Content

    • nacerbaaziz
      By nacerbaaziz
      hi dears
      am using an ini files as a History
      Sometimes the file size is be larger to 5 MB
      AutoIt does not recognize the full content of the file
      When I did a search to find out why, I discovered that INI files could not be read if they size larger than 64 KB.
      for that I preferred to ask here if is there any way to bypass this obstacle.
      The contents of the file are  as follows
      [filesList]
      c:\...\...\f1.mp3=00:15:20
      c:\...\...\f2.mp3=00:10:20
      c:\...\...\f3.wav=00:59:20
      ....... Etc
      This is the section for reading the file (adapted from my main script)

      case $continue     Local $aArray = IniReadSection($WaitingListFile, StringEncrypt(true, "filesList", $MyPassword))     If Not @error Then Opt("GUICloseOnESC", 1) _GUICtrlListView_DeleteAllItems($scList)         For $i = 1 To $aArray[0][0] $path = path_list(StringEncrypt(false, $aArray[$i][0], $MyPassWord), 1) if FileExists(StringEncrypt(false, $aArray[$i][0], $MyPassWord)) then GUICtrlCreateListViewItem(_GetFileName(FileGetLongName(StringEncrypt(false, $aArray[$i][0], $MyPassWord))) & Opt("GUIDataSeparatorChar") & " : " & Opt("GUIDataSeparatorChar") & FileGetLongName(StringEncrypt(false, $aArray[$i][0], $MyPassWord)), $scList) else $path = $path endIf         Next GUISetState(@sw_disable, $hGUI) GUISetState(@sw_show, $hGUI2) GUICtrlSetState($SClist, $GUI_FOCUS) else if $accessibilitymode = 1 then speak(str("listEmpty")) endIf endIf
      Is there any way to solve this problem, please?
      am waiting your answers...
      Greetings to All
    • AndreasNWWWWW
      By AndreasNWWWWW
      Hi, i'm just curious is there a way to sort an ini file after largest first?
      my inifiles writes itself like this
      14=500
      13=GREY
      12=500
      11=600
      10=600
      9=600
      8=700
      7=700
      5=600
      3=600
      2=800
      1=700
      15=GREY
      4=GREY
       
      but is there a way so i can get it sortet 
      15
      14
      13
      12 
      etc?
    • AndreasNWWWWW
      By AndreasNWWWWW
      Hi, i'm curious if this is even possible, i want to do an action if the ini file contains current values under a section.
      for my test i'm looking for 100,200,300,400,500
      and if any of those excits i want to pop a msgbox with the number in the section.
      i can in my example find one, but it does not check everyone. why?  what am i missing?
      Local $iscore810[5] = [100,200,300,400,500] Local $iMax800 = 5 While 1 ;~     Send("{pause}") ;;func les ini fil     $var = IniReadSection("Area.ini", "modus")     If @error Then         MsgBox(4096, "Error", "Unable to read section.")     Else          For $number = 1 To $var[0][0] If $var[$number][1] == $iscore810[3] Then       MsgBox($MB_SYSTEMMODAL, "FAnt den på", $var[$number][0], 5) EndIf                       Next     EndIf     exit WEnd  
    • Pike
      By Pike
      Hello Everyone,
      New Guy here. This is a two-part question, hopefully easy enough though. I know it's ugly coding, this is because I have only a couple hours worth of coding experience and could really use some help.
      1) When I single click the button I want one action (like playing a sound clip) and when I double click the button I want a different action (such as opening dialogue box to ask for soundclip directory address). At the bottom of the script I made a comment which one I would like single click versus double click.
      2) I can not get the FileOpenDialogue to save the file address to the config.ini file at the 'One' position on the .ini.
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <FileConstants.au3> #include <AutoItConstants.au3> #include <Sound.au3> Opt('MustDeclareVars', 1) Opt("GUIOnEventMode", 1) Global $OneID _Main() Func _Main() GUICreate("Form1", 156, 86, 281, 276) $OneID = GUICtrlCreateButton("Button", 15, 17, 122, 37) GUICtrlSetOnEvent($OneID, "OnOne") GUISetOnEvent($GUI_EVENT_CLOSE, "OnExit") GUISetState() While 1 While 1 Sleep(1000) WEnd WEnd EndFunc ;---------------Functions------------- While 1 Sleep(100) WEnd Func OnOne() ; ******************Single Click for this action**************** $OneID = IniRead("config.ini", "Config", "One", $OneID) If $OneID = True Then SoundPlay($OneID, @HotKeyPressed) Else ; *******Double Click for this action*****And Help Saving File Address to config.ini 'One'*********** $OneID = FileOpenDialog("Select file", @WorkingDir, "All (*.*)") IniWrite("config.ini", "Config", "One", $OneID) $OneID = InputBox("Enter Information", "Short Name for File?", "") IniWrite("config.ini", "Config", "NameOne", $OneID) EndIf EndFunc Any help would be greatly appreciated, and if you need anymore clarity as to what exactly I'm trying to do, please do not hesitate to ask. Thanks so much!
      Pike
    • kartune
      By kartune
      Hi, i would like to know if there is a possible way to use subsections for ini files?
      For example, my ini file would look something like this:
       
      Clientname.ini
      [Info]
      Country=USA
      Type=Distributor
       
      [Costs]
      [[JAN]] <----- subsection
      cost1=----
      cost2=----
      [[FEB]]
      cost1=----
      cost2=----
       
      [Sales]
      [[JAN]] <----- subsection
      sale1=----
      sale2=----
      [[FEB]]
      sale1=----
      sale2=----
       
      [Profits]
      [[JAN]] <----- subsection
      prof1=----
      prof2=----
      [[FEB]]
      prof1=----
      prof2=----
       
      The sales would be inputed everyday by the script, and then whenever viewed, i would be using an array to view every sale/cost/profit under the subsection
       
       
      Thanks for your time!
×