Question Parsing d'un fichier INI sans blocage en écriture

Plus d'informations
il y a 2 ans 2 mois - il y a 2 ans 2 mois #31694 par Damien
Bonjour à tous,

Je souhaite via Powershell parser un fichier INI (caractérisé par la présence de sections et clés). Je dois malheureusement lutter contre des écritures sur le fichier INI provenant d'un autre processus que je ne peux ni contrôler, ni bloquer...

Ci-dessous, un extrait du fichier ini :

[General]
name=Test
pid=123
[Other]
type=Linux

ll faut donc que je récupère son contenu sans aucun block sur le fichier...

Bien entendu, après de la doc et des travaux disponibles sur Internet, j'ai intégré les codes disponibles ici :
gist.github.com/hsmalley/3836383
superuser.com/questions/1184789/powershe...file/1185141#1185141

afin d'obtenir le code suivant :
[code]# Lecture du fichier
function Get-IniContent ($filePath)
{

    [System.IO.FileStream] $fileStream = [System.IO.File]::Open("$filePath", [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)

    $byteArray = New-Object byte[] $fileStream.Length
    $encoding = New-Object System.Text.UTF8Encoding $true

    while ($fileStream.Read($byteArray, 0 , $byteArray.Length)) {
        $encoding.GetString( $byteArray )
    }

    $fileStream.Dispose()

    # Debug
    write-host $encoding.GetString( $byteArray )

    switch -regex ($encoding.GetString( $byteArray ))
    {
        "^\[(.+)\]" # Section
        {
            $section = $matches[1]
            $ini[$section] = @{}
            $CommentCount = 0
        }
        "^(;.*)$" # Comment
        {
            $value = $matches[1]
            $CommentCount = $CommentCount + 1
            $name = "Comment" + $CommentCount
            $ini[$section][$name] = $value
        } 
        "(.+?)\s*=(.*)" # Key
        {
            $name,$value = $matches[1..2]
            $ini[$section][$name] = $value
        }
    }

    return $ini

}

# Test
$File = Get-IniContent "c:\Program Files\Airmont\Airmont Gateway\config.ini"
write-host "res1: "$File.General.name
write-host "res2: "$File.VirtualBox.vbType
[/code]

Malheureusement, j'obtiens l'erreur suivante :

Indexation impossible dans un tableau Null.
Au caractère C:\Users\DJO\Desktop\test.ps1:24 : 4
+             $ini[$section] = @{}
+             ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation : ( , RuntimeException
+ FullyQualifiedErrorId : NullArray

Indexation impossible dans un tableau Null.
Au caractère C:\Users\DJO\Desktop\test.ps1:37 : 4
+             $ini[$section][$name] = $value
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation : (, RuntimeException
+ FullyQualifiedErrorId : NullArray

Mon sentiment est que cela provient du format de $encoding.GetString( $byteArray ), mais je ne parviens pas à trouver la bonne solution. J'ai aussi tenté de passer par un fichier temporaire avant l'utilisation du "swith" mais seul la première ligne était retournée...

Auriez-vous une piste ?

Merci.
DJ
 
Dernière édition: il y a 2 ans 2 mois par Damien.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 2 mois #31698 par Philippe
salut Damien

il manque l'initialisation de ton tableau $ini avant le switch
$ini = @{}
switch -regex .......
Les utilisateur(s) suivant ont remercié: Damien

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 2 mois #31702 par Damien
Bonjour Philippe,

Effectivement, j'avais zappé l'initialisation du tableau... Du coup, je n'ai plus l'erreur d'un tableau Null...

Par contre, si je mets :
write-host $ini.General.name
write-host $ini.VirtualBox.vbType
return $ini

avant de vérifier si j'ai bien mes valeurs, seul $ini.General.name me retourne quelque chose... $ini.VirtualBox.vbType lui est vide...

Une idée ?

Merci de ton aide.
DJ
 

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 2 mois #31703 par Damien
Re-bonjour Philippe,

Pour info, cette fois si je passe par un fichier temporaire comme ci-dessous :
function Get-IniContent ($filePath)
{

    [System.IO.FileStream] $fileStream = [System.IO.File]::Open("$filePath", [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)

    $byteArray = New-Object byte[] $fileStream.Length
    $encoding = New-Object System.Text.UTF8Encoding $true

    while ($fileStream.Read($byteArray, 0 , $byteArray.Length)) {
        $encoding.GetString( $byteArray )
    }

    $fileStream.Dispose()

    $encoding.GetString( $byteArray ) | Out-File -FilePath .\res.ini

    $ini = @{}

    switch -regex -File .\res.ini
    {
        "^\[(.+)\]" # Section
        {
            $section = $matches[1]
            $ini[$section] = @{}
            $CommentCount = 0
        }
        "^(;.*)$" # Comment
        {
            $value = $matches[1]
            $CommentCount = $CommentCount + 1
            $name = "Comment" + $CommentCount
            $ini[$section][$name] = $value
        } 
        "(.+?)\s*=(.*)" # Key
        {
            $name,$value = $matches[1..2]
            $ini[$section][$name] = $value
        }
    }

    write-host $ini.General.name
    write-host $ini.VirtualBox.vbType
    return $ini

}

les variables $ini.General.name et $ini.VirtualBox.vbType sont OK... Mais j'aimerais quand même éviter cette opération.

Merci.
DJ

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 2 mois - il y a 2 ans 2 mois #31711 par Philippe
je t'avoue que je ne vois pas pourquoi mais je n'ai fais qu'une simple lecture de ton script et je n'ai pas eu de temps pour faire un test aujourd'hui
je pense que c'est un problème de type de variable dans $section ou peut être dans $value ou $name
quoi qu'il en soit tu dois vérifier leurs type avec $section.gettype()

autre possibilité que je vois au moment ou j'écris ceci un espace au début ou fin de variable
tu peux les supprimer avec un trim :
$section.Trim()

si j'ai un peu de temps demain, je regarde de plus prés !!
Dernière édition: il y a 2 ans 2 mois par Philippe.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.075 secondes
Propulsé par Kunena