Scope/persistence 数据问题

Scope/persistence of data issue

我不确定要搜索什么来解决这个问题。我有一个 scope/persistence 的数据问题,其中用于填充我的数据结构的变量覆盖了数据结构 (ImageFileName) 中的其他项目。这是我的代码:

###Functions...first two are just for info

#method to get messages for mdb files 
#dependency-Need to download accessDatabaseEngine(64 bit) redestributable: https://www.microsoft.com/en-us/download/details.aspx?id=54920
Function ProcessHelpMDB{
[cmdletbinding()]
  Param ([string]$mdbLookupError, [string]$mdbFilePath, [string]$mdbDeviceSeries) #$mdbLookupError = error number, like 701. $mdbDeviceSeries is 1000
  Process
  {

    #Write-Host "mdbLookupString: $mdbLookupString" -ForegroundColor Cyan
    $adOpenStatic = 3
    $adLockOptimistic = 3
    #Write-Host "In ProcessMDB" -ForegroundColor darkRed
    #$pathViewBase = 'C:\me\EndToEnd_view\' #View dir. Maybe param later

    #$pathToMdb = Join-Path -Path $pathViewBase -ChildPath $mdbFileName

    $deviceTable = $mdbDeviceSeries + "PP"
    $mdbLookupError -Match '[0-9]*-([0-9]*)'
    $errLookup = $Matches[1]

    #Write-Host "dps" -ForegroundColor DarkMagenta

    $selectQuery = “SELECT [$($deviceTable)].[HelpCode],
    [$($deviceTable)].[ScreenNumber],
    [$($deviceTable)].[TextID],
    [$($deviceTable)].[PictureID]
        FROM [$($deviceTable)]
        WHERE 
            [$($deviceTable)].[HelpCode] = $($errLookup)"


    $cn = new-object -comobject ADODB.Connection
    $rs = new-object -comobject ADODB.Recordset

    $cn.Open("Provider = Microsoft.ACE.OLEDB.16.0;Data Source = $mdbFilePath") 
    $rs.Open($selectQuery,
        $cn, $adOpenStatic, $adLockOptimistic)

    $i=0
    $ret = [System.Collections.Generic.List[psobject]]::new() 

    if($rs.EOF)
    {
        Write-Host "$mdbLookupString not in $mdbFileName...record set returned emtpy for query"
    }#if
    else
    {  
        while($rs.EOF -ne $True)
        {
            $result = [ordered]@{}
            #$hash = @{}
            foreach ($field in $rs.Fields)
            {
                $result[$field.name] = $field.Value
            }#result
            $newObject = [PSCustomObject]$result
            $ret.Add($newObject) #
            $rs.MoveNext()
        } #while
    }#else
    Write-Host "retArr[0] $($ret[0])" #prints retArr[0] @{PictureID=HELP_...; TextID=HELP_...; HelpCode=9; ScreenNumber=1}
    $i=0
    foreach($row in $ret) #goes thru all rows
    {
        Write-Host "retArr[0] $($ret[$i,"TextID"])" #prints retArr[0] @{HelpCode=9; ScreenNumber=1; TextID=HELP_...; PictureID=HELP_...}
        ####
        Write-Host "retArr[] $($row)" #prints retArr[] @{HelpCode=9; ScreenNumber=1; TextID=HELP_...; PictureID=HELP_7000_POWER_COVER_RIBBON}
        Write-Host "retArr[0] $($row[$i])" #prints retArr[0] @{HelpCode=9; ScreenNumber=1; TextID=HELP_...; PictureID=HELP_...}
        $i++
    }

    foreach($row in $ret.GetEnumerator()) #this is working for each row
    {
        Write-Host $row.TextID #prints HELP_...
        Write-Host $row.'TextID' #prints HELP_...
    }

    $ret | ForEach-Object {
        Write-Host TextID= $($_.TextID) #prints TextID= HELP_...
        Write-Host TextID= $($_.'TextID') #prints TextID= HELP_...
    } #
       
    $cn.Close()
    return $ret #Items queried from db ################################################# need to put them in excel file in order next
  } #end Process
}# End of Function process mdb's

    
#This function gets mdb info out and returns English-US message found
Function ProcessK_MDB{
    [cmdletbinding()]
      Param ([string]$mdbLookupstring) #$mdbLookupString like HELP_...
      Process
      {
        $adOpenStatic = 3
        $adLockOptimistic = 3

        $pathViewBase = 'C:\me\EndToEnd_view\' #View dir. Maybe param later
        $mdbFileNamePath = 'KAppText.mdb'
    
        $pathToMdb = Join-Path -Path $pathViewBase -ChildPath $mdbFileNamePath

        if(Test-Path $pathToMdb)
        {
            $selectQuery = “SELECT [Messages].[Message Description],
            [Messages].[English - Us]
                FROM [Messages]
                WHERE [Messages].[Message Description] = '$($mdbLookupString)'”
   
            $cn = new-object -comobject ADODB.Connection
            $rs = new-object -comobject ADODB.Recordset
            $cn.Open("Provider = Microsoft.ACE.OLEDB.16.0;Data Source = $pathToMdb")
           
            $rs.Open($selectQuery,
                $cn, $adOpenStatic, $adLockOptimistic)
        
            if($rs.EOF) #empty
            {
                Write-Host "$mdbLookupString not in $mdbFileName...record set returned emtpy for query"
                $ret = ""
            }#if
            else #got results
            {  
                $returnArr = $rs.GetRows()
                #$ret = $returnArr[0,1]
                #$ret2 = $returnArr[1,1]
                $ret = $returnArr[1,0] #has long text
                #$ret4 = $returnArr[0,0] #has short text
                #Write-Host $ret

            }#else got results    
            
            $cn.Close()
        } #testPath
        else {
            Write-Host "$pathToMdb does not exist"
        }
        return $ret #Message English-US for parameter/Message Description given
      } #end Process
    }# End of Function process mdb's

Function Get-ImageName{
    [cmdletbinding()]
      Param ([string]$imageName, [string]$fileNamePath) 
      Process
      {
        #find image file name to look for
        [System.String] $pictureName = ""
        if($imageName -Match "HELP")
        {
            #remove "HELP" part of file name
            $($row.PictureID) -Match "HELP_(.*)" #get the part after HELP_
            Write-Host $Matches[0]
            Write-Host $Matches[1]
            $pictureName = $Matches[1]
        }
        else {
            $pictureName = $imageName
        }

        $imageFile2 = Get-ChildItem -Recurse -Path $ImageFullBasePath -Include @("*.bmp","*.jpg","*.png") | Where-Object {$_.Name -match "$($pictureName)"}  #$imageFile | Select-String -Pattern '$($pictureName)' -AllMatches
        Write-Host "ImageFile2: $($imageFile2)"
        $imgFile = ""
        foreach($imgFile in $imageFile2) #there may be more than one...just get last one...there are multiple telephone images
        {
            if($imgFile.Exists) #if($imageFile2.Exists)
            {
                #$image = [System.Drawing.Image]::FromFile($imgFile) #may not need this step
                #need to figure out which is correct if there's multiple images
                return $imgFile
            }
            else {
                Write-Host "$($imgFile) does not exist"
                return $null
            }
        } #foreach imageFile2
        return $null
      } #end Process
    }# End of Function process mdb's

###main####

          $resultHelp = ProcessHelpMDB -mdbLookupError $errCode -mdbFilePath $basePathFull -mdbDeviceSeries $deviceVer #######
          $result = foreach($row in $resultHelp.GetEnumerator()) #this is working for each row
          {
              if($row -ne $True) #not sure why it adds true at the top
              {
                Write-Host $row.TextID #prints HELP_...
                #lookup value from kapptext.mdb
                Write-Host $($row.TextID) #prints nothing but looks ok in next function
                $longText = ProcessK_MDB -mdbLookupstring $($row.TextID) #gives English-US message from device for parameter given
                #insert images######################
                #I can see that these are assigned correctly and returned from Function:
                [System.Drawing.Image] $image = New-Object System.Drawing.Image  #error...see Update2
                [System.String] $imageNamePath = New-Object System.String  #error...see Update2
                [System.String] $imageNamePath = Get-ImageName -imageName $($row.PictureID) -fileNamePath $ImageFullBasePath
                if($null -ne $imageNamePath)
                {
                    $image = Get-Image -imageFileName $imageNamePath
                }
                else 
                {
                    Write-Host "Did not find an image file for $($row.PictureID) in $ImageFullBasePath"
                }
                #get the data ready to put in spreadsheet
                 New-Object psobject -Property $([ordered]@{
                    ScreenNumber = $($row.ScreenNumber)
                    KPMKey = $($row.TextID)
                    EnglishUS = $($longText)
                    PictureID = $($row.PictureID)
                    ImageFound = ""
                    ImageFileName = $($imageNamePath) ###???this is over-written...all same in $result after done with loop
                })
              } #if not true
          } #foreach row $resultHelp

##注意:$image 稍后会插入到电子表格中,但由于使用 $results 时名称显示不正确,所以我不分享该部分。

我可以看到在运行 9 行之后,$result 中的每个 ImageFileName 都是相同的。我该怎么做才能维护从方法返回的内容?现在我正在尝试使用 New-Object,但它并没有解决问题。

这是 $resultHelp 的样子:

[0] $true (I'm not sure why it puts true at the top) [1] @(HelpCode=9;ScreenNumber=1;TextID=HELP_...JA;PictureID=HELP_...RIB) [2] @(HelpCode=9;ScreenNumber=2;TextID=HELP_...ROLL;PictureID=HELP_...ROLL) [3] @(HelpCode=9;ScreenNumber=3;TextID=HELP_...EDGE;PictureID=HELP_...UT) ...

我正在使用 Powershell 5.1 和 VSCode。

更新:

我再次检查,在 Get-ImageName 中,它返回一个类似“Contact_Service”...bmp 的文件名,看起来它被放入 psObject ImageFileName...($imageNamePath) ,对于找到的其他图像也是如此。当我最后查看时,$result 对那个 ImageFileName 具有所有相同的值。和以前说“Contact_Service”..bmp 的那个现在是另一回事,与 $result.

中的其他匹配

更新 2:

有几个错误:

New-Object : A constructor was not found. Cannot find an appropriate constructor for type System.Drawing.Image

New-Object : A constructor was not found. Cannot find an appropriate constructor for type System.String.

对于我在主代码中尝试处理对象覆盖问题的地方

更新 3:

在我将 psobject 整理好后,我将其放入带有 Export-Excel 的电子表格中。我只是想提供此信息,以便您知道我为什么将其放在 psobject 中:

$xlsx = $result | Export-Excel -Path $outFilePath -WorksheetName $errCode -Autosize -AutoFilter -FreezeTopRow -BoldTopRow  -PassThru # -ClearSheet can't ClearSheet every time or it clears previous data  
  

我想通了。

问题是,即使我找到不同的 $imageNamePaths 以分配给 属性 作为每个 PictureID 的 ImageFileName,并在 foreach 循环中的 psobject 中分配这些属性,我最终还是得到了每个 ImageFileName 属性(覆盖)都一样。这修复了它。

New-Object psobject -Property $([ordered]@{
   ScreenNumber = $($row.ScreenNumber)
   KPMKey = $($row.TextID)
   EnglishUS = $($longText)
   PictureID = $($row.PictureID)
   ImageFound = ""
   ImageFileName = "$($imageNamePath)"    ####added double quotes
})

双引号让不同的 $imageNamePath 值保留而不是 over-written。我不太清楚为什么。

谢谢@Mathias,我将抑制我的 -Match 的输出,以查看是否从函数返回的数据顶部删除了 $true。 :)