Jump to content

Equal data in For...In Loop not matching


Recommended Posts

I was originally trying to create a function here:

Where I wanted to check if $sModel had data in it before executing. The app actually will work if I leave the check off, but I don't want it to do that. So I researched and tried some different ways to verify that the data was not only present, but was allowed to be used. My best guess was to compare the value of $sModel to an INI file, because that var can have data in it that doesn't match to available programs to run. So the proof of concept works, however once I introduce that code into my application, the new For loop does not work.

So I am wondering if there is a problem having two For Loops in the same function, or if my For variable needs to be changed. Example:

For $i = 1 to $bin[0]
        If $bin[$i] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34))
        EndIf
    Next
    For $i = 1 to $Sections[0]
        If GUICtrlRead($Radio[$i]) = $GUI_CHECKED Then
            MsgBox (4096, "var", $vnm[$i])
        EndIf
    Next

The one pointing to $bin does not work, but the one for $sections works fine.

It (proof of concept) does, however, work fine on its own:

#include <Array.au3>
    Global $sModel, $bin
    $sModel = "model"
    $bin = IniReadSectionNames("v:\allowed.ini")
    For $i = 1 to $bin[0]
        If $bin[$i] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34))
        EndIf
    Next
Edited by Tripredacus
Link to comment
Share on other sites

I actually use 2 For Loops in a single func in a couple automation scripts at work. I bet it is because you are using the same $i variable for both because when it enters the 2nd For loop, the variable gets reset. Use 2 different vars :huh2:

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

I switched to using $j for the $bin but that didn't change either. I am actually doing a RunWait after Then, so I changed to MsgBox and that didn't do anything either. I added MsgBox before the For Loop to verify that the $sModel had data in it, and it does. So that section looks like this now:

MsgBox (64, "Win32_BaseBoard Item", $sModel )
    For $j = 1 to $bin[0]
        If $bin[$j] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34))
        EndIf
    Next
    For $i = 1 to $Sections[0]
        If GUICtrlRead($Radio[$i]) = $GUI_CHECKED Then
            MsgBox (4096, "var", $vnm[$i])
        EndIf
    Next

I also thought that maybe it didn't like me wrapping the path in quotes, but that shouldn't effect it in MsgBox form.

Do I need to declare $j? I notice I am declaring $i as Local, but $bin as Global. Should either matter?

Link to comment
Share on other sites

damn that's 2x today so far.

Somehow I read it as a For...Next inside a For...Next.

have you tried using Ubound($yourvar)-1 (or just UBound($yourvar) if 0 is not the number of elements) instead of $yourvar[0]? I've found it is much more accurate and less prone to errors if 0 is not the number of elements in the array.

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

I am going to wager that the existance of the 2 For Loops isn't the actual problem. I did a check and it appears that $bin has no data in it when the Function runs.

However, this is interesting, if I put the MsgBox in my test code that "DOES" return the value I want, $bin also comes up as being empty.

#include <Array.au3>
    Global $sModel, $bin
    $sModel = "Model"
    $bin = IniReadSectionNames("v:\allowed.ini")
    MsgBox (64, "Bin", $bin)
    For $i = 1 to $bin[0]
        If $bin[$i] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34))
        EndIf
    Next

So I am definately not using the $bin var properly? But why would I get the MsgBox in the test code but not in the actual program?

Link to comment
Share on other sites

Yes. I'm changing the name to protect the innocent. My script gets that value from WMI. I've also tested putting that INI in a local folder (rather than network drive) but no difference. But besides, other parts of the app read INI from the server and have no problem.

The INI is just a bunch of sections without data. It was the best idea I could come up with, seemed easier than reading a text file. Here is an example:

[Model]
[section]
[section2]
[bananas]

Etc, no values. So if $bin isn't returning anything in MsgBox. When it comes up, the window is blank except for the title, picture and OK button do show up.

Edited by Tripredacus
Link to comment
Share on other sites

Since you added the Model section name to the ini, then Model will equal Model even if there are no values in the section. So the question is does the real ini have the "Model" section name?

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

Since you added the Model section name to the ini, then Model will equal Model even if there are no values in the section. So the question is does the real ini have the "Model" section name?

Yes it does. I changed my example post to specify "Model" because it is an actual product name. Originally I was using the name that already existed in the WMI "Spring Peak" but my first thought of this problem was that there was a problem with the space in the value. That's why I have quotes around my path. So I had tested and changed that part of the BIOS to our internal product number instead. Besides, as I noted before the code DOES work outside of my main app. I noticed I didn't post the full, I guess I can:

#include <file.au3>
#include <array.au3>
Global $bin
Global $itdid, $objWMIService, $colItems, $sWMIService, $sName, $sModel, $uuItem, $objSWbemObject, $strName, $strVersion, $strWMIQuery, $objItem, $uiDitem, $strDesc
$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
    $bin = IniReadSectionNames("v:\allowed.ini")
IF IsObj($objWMIService) Then
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem")
    If IsObj($colItems) Then
        For $oItem In $colItems
            $sName = $oItem.Manufacturer
            $sModel = $oItem.Model
        Next
    EndIf
    For $i = 1 to $bin[0]
        If $bin[$i] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34))
        EndIf
    Next
EndIf

The above code works, at least the MsgBox appears. taking that code into my regular app doesn't work. Main differences is that my regular app is a GUI and the For Loop that shows the MsgBox is inside of a function rather than just the next thing it does.

Link to comment
Share on other sites

This is probably something so simple.

If I understand correctly, just the part you posted works fine, but when intergrated into the main app it does not find a match between $bin and $sModel. No crashing or errors, just does not find a match...

Something I just noticed with the above code, you have your first loop run through $colItems and sets $sModel each time, so when it enters the 2nd For...Next, the value of $sModel is whatever was last in the $colItems group.

Another possability is that $sModel is losing it's value or the value is changing by some other code when the script changes functions maybe? Perhaps adding a console write or msgbox right before the 2nd For...Next just to check the value of $sModel to be sure?

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

Think of the WMI like a table in the database, but with only 1 column. So there is only 1 field that will go into $sModel. I do have it select * yes but I could just select the Model entry. Either way, there is only one so it doesn't get changed at any point.

I also have my GUI show the variable, so I know it isn't disappearing at that point. I also set MsgBox before and after the For Loop, and the data is present in each.

$Label1 = GUICtrlCreateLabel("Detected Hardware as: " & $sModel, 32, 20, 170, 30)

And the MsgBox placement.

MsgBox (0, "VarCheckBefore", $sModel)
        For $i = 1 to $bin[0]
        If $bin[$i] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34) & @error)
                EndIf
            Next
            MsgBox (0, "VarCheckAfter", $sModel)

However, here's a step in the right direction! Using this gives me 5 blank MsgBox. 5 is a key number because there are 5 sections in the version.ini!

For $i = 1 to $bin[0]
        MsgBox (64, "Bin value", $bin )
            Next

OK I'm embarrassed now maybe. This returns the values from the INI:

For $r = 1 to Ubound($bin) - 1
MsgBox (64, "Bin value", $bin[$r] )
Next

I'm going to rebuild and try again.

Update: Nope I'm still not getting the MsgBox... Updated code:

For $r = 1 to Ubound($bin) - 1
        If $bin[$r] = $sModel Then
        ;MsgBox (64, "Bin value", $bin[$r] )
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34) & @error)
       EndIf
            Next
Edited by Tripredacus
Link to comment
Share on other sites

I have confirmed that both $sModel has the correct data in it AND that $bin[5] has the matching data to $sModel. But for some reason the For statement doesn't return a match.

MsgBox (4096, "bin5", $bin[5])
                MsgBox (4096, "sModel", $sModel)
        For $r = 1 to Ubound($bin) - 1
        If $bin[$r] = $sModel Then
            MsgBox (64, "Win32_BaseBoard Item", @ComSpec & " /c " & Chr(34) & "x:\windows\system32\" & $sModel & ".cmd" & Chr(34) & @error)
       EndIf
            Next
Link to comment
Share on other sites

I am at a loss, the only reason you should not be getting a msgbox is if the values don't match. Something is causing them to not be equal :huh2:

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

Try this:

If StringStripWS($bin[$r], 8) = StringStripWS($sModel, 8) Then

;)

This at least showed me why my previous attempts to execute programs didn't work. The string being returned in $sModel (which the GUI label didn't seem to care about) had a huge amount of whitespace after it. So I had to use StringStripWS on the execution part (or in the MsgBox example I posted instead) because then it couldn't find "model .cmd" :huh2:

But anyways, I had thought about stripping white space, however I had not seen it anywhere in my earlier testing. I figured if I had used

$sModel & ".cmd"

I could see if there was a space before the .cmd part, and it did not show up, at least in MsgBox. Also I was not aware of that exact Function, or to say I haven't used it in AutoIT before. I am doing the final test now but it looks like this finally works. Thanks psaltyds, you always seem to be a great help around here! You too koatkbliss, you were right, it is almost always something really simple.

Link to comment
Share on other sites

I wanted to update this a little. I found where the whitespace was coming from. It was due to how the program we used to write to the DMI worked. It has a text file it reads from, and there were about 20-30 spaces after the model number. This was caused by using the EDIT.COM program, which every time you would edit the text file, a space would appear at the end of the line.

So it looks like my code ended up being correct (with help) and would have worked without stripping white space if the DMI tool wasn't bugged. Weird isn't it!

Link to comment
Share on other sites

  • 10 months later...

Sorry to bump an old topic, but I am working on using portions of the code in this one, and see if anyone had any idea. As you can read in this topic, the solution was to use StringStripWS on the vars.

So let me ask you this question now... Why would this work:

If StringStripWS($bin[3], 8) = StringStripWS($sModel, 8) Then

But this not work?

If StringStripWS($bin[$r], 8) = StringStripWS($sModel, 8) Then
Link to comment
Share on other sites

I just had a thought. The original code in this topic was created in an older version of AutoIT. Specifically, a version where @OSArch read as "WIN_2008" on a Windows 7 PC, and the version I am trying now @OSArch will read "WIN_7." Is it possible that something else has changed with the parser to make this code no longer work properly?

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...