IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez .NET Discussion :

[C#]Parseur de fichier .reg


Sujet :

Contribuez .NET

  1. #1
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut [C#]Parseur de fichier .reg


    Vu qu'une fois de plus j'ai du le faire moi même ... ()
    Voici donc un parseur de fichier .reg. Il prend en entrée un StreamReader (tout en sachant que normalement un fichier reg c'est de l'unicode pas de l'ascii, du moins de puis Windows 2000/XP) et en sortit donne une arborescence de clefs/valeurs sous formes de classes. Normalement ça gère bien toutes les valeurs hexa en les convertissant en string pour les MULTI_SZ entre autre et il reconnais certains caractères d'échappements.

    Normalement c'est du C# 3.0, mais c'est juste la manière d'écrire les propriétés qui poserai problème à une utilisation à partir de VS 2005 (vu que ça marche en C# 2.0 avec VS 2008). Donc si ça pose problème, il suffit de compléter les propriétés avec les champs correspondants.

    Le code donc :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Data;
     
    namespace DreamShield.Deployment.Utils
    {
        /// <summary>
        /// Classe qui permet de représenter les clefs du registre.
        /// Partout où une variable name est utilisée, il s'agit d'un chemin
        /// au sens du registre qui peut être HKEY_LOCAL_MACHINE\Microsoft\Windows
        /// ou encore CurrentVersion\Uninstall.
        /// </summary>
        public class LocalRegistryKey
        {
            #region Constants
     
            public const string HKLM = "HKEY_LOCAL_MACHINE";
            public const string HKCU = "HKEY_CURRENT_USER";
            public const string HKCR = "HKEY_CLASSES_ROOT";
            public const string HKU = "HKEY_USERS";
     
            #endregion
     
            #region Creation
     
            /// <summary>
            /// Crée un nouvel objet de registre.
            /// La clef renvoyée est un "parent virtuel" qui contient les clefs
            /// HKLM, HKCU, HKCR et HKU
            /// </summary>
            /// <returns></returns>
            public static LocalRegistryKey CreateRepository()
            {
                LocalRegistryKey res = new LocalRegistryKey(null, null);
                res.Childs.AddRange(new LocalRegistryKey[]{
                        new LocalRegistryKey(null, HKLM),
                        new LocalRegistryKey(null, HKCU),
                        new LocalRegistryKey(null, HKCR),
                        new LocalRegistryKey(null, HKU)
                    });
                res.GlobalRoot = true;
     
                return res;
            }
     
            #endregion
     
            #region Globals & Constructor
     
            /// <summary>
            /// Clef parente, null pour les clefs racines
            /// </summary>
            public virtual LocalRegistryKey Parent { get; protected set; }
     
            protected List<LocalRegistryKey> Childs { get; private set; }
     
            /// <summary>
            /// Clefs enfantes
            /// </summary>
            public virtual LocalRegistryKey[] SubKeys
            {
                get { return Childs.ToArray(); }
            }
     
            private LocalRegistryKey(LocalRegistryKey parent, string name)
            {
                if (parent != null && String.IsNullOrEmpty(name))
                    throw new ArgumentNullException("name");
     
                GlobalRoot = false;
                Parent = parent;
                _name = name;
     
                Childs = new List<LocalRegistryKey>();
     
                if (!GlobalRoot)
                {
                    InitRegValues();
                }
            }
     
            #endregion
     
            #region Access
     
            /// <summary>
            /// Indique si cette clef est le parent virtuel des clefs racines
            /// </summary>
            public virtual bool GlobalRoot { get; protected set; }
     
            /// <summary>
            /// Indique si la clef actuelle est une racine
            /// </summary>
            public virtual bool IsRoot
            {
                get { return Parent == null; }
            }
     
            string _name = null;
     
            /// <summary>
            /// Nom de la clef. Il ne peut être modifié que pour les clefs non racines
            /// </summary>
            public virtual string Name
            {
                get
                {
                    return _name;
                }
                set
                {
                    if (IsRoot)
                        throw new InvalidOperationException("Impossible de renommer une racine");
                    else
                    {
                        if (String.IsNullOrEmpty(value))
                            throw new ArgumentNullException("value");
                        else if (String.Equals(_name, value, StringComparison.OrdinalIgnoreCase))
                            _name = value;
                        else
                        {
                            if (Parent.KeyExists(value))
                                throw new DuplicateNameException(value);
                            else
                                _name = value;
                        }
                    }
                }
            }
     
            /// <summary>
            /// Indique si la clef spécifiée existe
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public virtual bool KeyExists(string name)
            {
                LocalRegistryKey key = null;
                return TryGetKey(name, out key);
            }
     
            /// <summary>
            /// Obtients une clef (exception si elle n'existe pas)
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public virtual LocalRegistryKey Key(string name)
            {
                return Key(name, false);
            }
     
            /// <summary>
            /// Charge la clef en la créant si elle n'existe pas et que canCreate vaut true.
            /// </summary>
            /// <remarks>Aucune clef ne peut être crée au même niveau que les clefs racines</remarks>
            /// <param name="name"></param>
            /// <param name="canCreate">Indique si la clef doit être crée si elle n'existe pas</param>
            /// <returns></returns>
            public virtual LocalRegistryKey Key(string name, bool canCreate)
            {
                LocalRegistryKey key = null;
                if (TryGetKey(name, out key, canCreate))
                    return key;
                else
                    throw new KeyNotFoundException(name);
            }
     
            /// <summary>
            /// Tente d'obtenir la clef spécifiée et la renvoi si elle existe, ou renvoi
            /// nul sinon dans key
            /// </summary>
            /// <param name="name"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            public virtual bool TryGetKey(string name, out LocalRegistryKey key)
            {
                return TryGetKey(name, out key, false);
            }
     
            protected virtual bool TryGetKey(string name, out LocalRegistryKey key, bool canCreate)
            {
                if (String.IsNullOrEmpty(name))
                    throw new ArgumentNullException("value");
     
                string[] secs = name.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
     
                key = this;
     
                for (int i = 0; i < secs.Length; i++)
                {
                    key = FindKey(key, secs[i], canCreate);
                    if (key == null)
                        break;
                }
     
                return key != null;
            }
     
            protected virtual LocalRegistryKey FindKey(LocalRegistryKey key, string name, bool canCreate)
            {
                if (String.IsNullOrEmpty(name))
                    throw new ArgumentNullException("name");
                if (name.Contains("]") || name.Contains("["))
                    throw new InvalidDataException("Nom invalide :" + name);
     
                foreach (var item in key.Childs)
                {
                    if (item.Name != null && item.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                        return item;
                }
     
                if (canCreate)
                {
                    if (key.GlobalRoot)
                    {
                        /* Impossible de créer une clef racine */
                        return null;
                    }
                    else
                    {
                        LocalRegistryKey n_key = new LocalRegistryKey(key, name);
                        key.Childs.Add(n_key);
                        return n_key;
                    }
                }
                else
                {
                    return null;
                }
            }
     
            #endregion
     
            #region Utils
     
            /// <summary>
            /// Efface tous le contenu des clefs
            /// </summary>
            /// <remarks>Ne peut pas être appelé sur la racine virtuelle</remarks>
            public virtual void Clear()
            {
                if (GlobalRoot)
                    throw new InvalidOperationException("Impossible de supprimer les clefs racines");
                else
                {
                    Childs.Clear();
                    Values.Clear();
                }
            }
     
            /// <summary>
            /// Supprime la clef
            /// </summary>
            /// <remarks>Une clef racine ne peut pas être supprimée.</remarks>
            public virtual void Delete()
            {
                if (IsRoot)
                    throw new InvalidOperationException("Impossible de supprimer une racine");
                else
                {
                    Parent.Childs.Remove(this);
     
                    Childs.Clear();
                    if (Values != null)
                    {
                        Values.Clear();
                    }
     
                    Values = null;
                    Childs = null;
                    Parent = null;
                    _name = null;
                }
            }
     
            /// <summary>
            /// Obtient le nom complet de la clef
            /// </summary>
            public virtual string FullName
            {
                get
                {
                    return (Parent != null ? Parent.FullName + "\\" : "") + Name;
                }
            }
     
            public override string ToString()
            {
                string s = FullName;
                return String.IsNullOrEmpty(s) ? base.ToString() : s;
            }
     
            #endregion
     
            #region Values
     
            /// <summary>
            /// Liste des valeurs.
            /// Pour la valeur par défaut, utiliser comme clef "" (la chaine vide), null étant une valeur
            /// de clef interdite
            /// </summary>
            public virtual Dictionary<string, LocalRegistryValue> Values { get; protected set; }
     
            protected static RegValueKeysComparer RegValueKeysComparerInstance = new RegValueKeysComparer();
     
            protected void InitRegValues()
            {
                Values = new Dictionary<string, LocalRegistryValue>(RegValueKeysComparerInstance);
            }
     
            /* Juste par sécurité */
            protected class RegValueKeysComparer : IEqualityComparer<string>
            {
                #region IEqualityComparer<string> Membres
     
                public virtual bool Equals(string x, string y)
                {
                    if (String.IsNullOrEmpty(x))
                        return String.IsNullOrEmpty(y);
                    else
                    {
                        return String.Equals(x, y, StringComparison.OrdinalIgnoreCase);
                    }
                }
     
                public virtual int GetHashCode(string obj)
                {
                    return obj == null ? 0 : obj.GetHashCode();
                }
     
                #endregion
            }
     
            #endregion
        }
     
        public class LocalRegistryValue
        {
            public LocalRegistryValue(ValueType vType, object vVal)
            {
                ValueType = vType;
                Value = vVal;
            }
     
            protected ValueType valueType = ValueType.Binary;
     
            /// <summary>
            /// Type de valeur
            /// </summary>
            /// <remarks>Changer de type efface automatiquement la variable Value</remarks>
            public virtual ValueType ValueType
            {
                get
                {
                    return valueType;
                }
                set
                {
                    if (valueType != value)
                    {
                        valueType = value;
                        _value = null;
                    }
                }
            }
     
            protected object _value = null;
     
            /// <summary>
            /// Valeur, doit être convertible en ValueType
            /// </summary>
            public virtual object Value
            {
                get { return _value; }
                set
                {
                    if (!CheckValue(ValueType, value))
                        throw new InvalidDataException(String.Format("L'argument {0} n'est pas convertible en {1}", value, ValueType));
                    else
                        _value = value;
                }
            }
     
            protected virtual bool CheckValue(ValueType ValueType, object value)
            {
                if (value == null)
                    return true;
                else
                {
                    switch (ValueType)
                    {
                        case ValueType.Binary: { return typeof(byte[]).IsAssignableFrom(value.GetType()); }
                        case ValueType.DWORD: { return typeof(uint).IsAssignableFrom(value.GetType()); }
                        case ValueType.QWORD: { return typeof(ulong).IsAssignableFrom(value.GetType()); }
                        case ValueType.MultiString: { return typeof(string[]).IsAssignableFrom(value.GetType()); }
                        case ValueType.ExpandableString:
                        case ValueType.String:
                            {
                                return typeof(string).IsAssignableFrom(value.GetType());
                            }
                        default: { return false; }
                    }
                }
            }
     
            public override string ToString()
            {
                return String.Format("{0}", Value);
            }
        }
     
        public enum ValueType
        {
            /// <summary>
            /// Binary registry value type : convertit en byte[]
            /// </summary>
            Binary,
            /// <summary>
            /// DWORD registry value type : convertit en uint
            /// </summary>
            DWORD,
            /// <summary>
            /// QWORD registry value type : convertit en ulong
            /// </summary>
            QWORD,
            /// <summary>
            /// Expandable string registry value type : convertit en string
            /// </summary>
            ExpandableString,
            /// <summary>
            /// MultiString registry value type : convertit en string[]
            /// </summary>
            MultiString,
            /// <summary>
            /// String registry value type : convertit en string
            /// </summary>
            String
        }
     
        public static class RegFileImporter
        {
            public static LocalRegistryKey ProcessRegistryFile(StreamReader input)
            {
                return ProcessRegistryFile(input, null);
            }
     
            public static LocalRegistryKey ProcessRegistryFile(StreamReader input, LocalRegistryKey result)
            {
                if (result == null)
                    result = LocalRegistryKey.CreateRepository();
     
                LocalRegistryKey last = null;
     
                string current_line = "";
                while (!input.EndOfStream)
                {
                    current_line = input.ReadLine();
                    if (current_line.StartsWith("["))
                    {
                        /* section */
                        int end = current_line.IndexOf("]");
                        if (end < 1)
                            throw new InvalidDataException("Ligne invalide :" + current_line);
                        else
                        {
                            string key_name = current_line.Substring(1, end - 1);
     
                            last = result.Key(key_name, true);
                        }
                    }
                    else if (current_line.StartsWith("@"))
                    {
                        /* valeur par défaut */
                        ReadValue(current_line, input, last);
                    }
                    else if (current_line.StartsWith("\""))
                    {
                        /* valeur nommée */
                        ReadValue(current_line, input, last);
                    }
                }
     
                return result;
            }
     
            private static void ReadValue(string current_line, StreamReader input, LocalRegistryKey last)
            {
                if (String.IsNullOrEmpty(current_line))
                    return;
                else
                {
                    string[] secs = current_line.Split(new char[] { '=' }, 2);
                    if (secs.Length != 2)
                        throw new InvalidDataException("Ligne invalide :" + current_line);
                    else
                    {
                        string name = secs[0];
                        string data = secs[1];
     
                        if (name == "@")
                            name = "";
                        else
                            name = name.Substring(1, name.Length - 2); /* On retire les quotes */
     
                        if (String.IsNullOrEmpty(data) || data == "\"\"")
                        {
                            last.Values[name] = new LocalRegistryValue(ValueType.String, null);
                        }
                        else
                        {
                            if (data.StartsWith("hex:")) // binary
                            {
                                last.Values[name] = new LocalRegistryValue(ValueType.Binary,
                                    (byte[])ParseBinaryArray(data.Substring("hex:".Length), input));
                            }
                            else if (data.StartsWith("dword:")) //dword
                            {
                                last.Values[name] = new LocalRegistryValue(ValueType.DWORD,
                                    (uint)ParseDword(data.Substring("dword:".Length), input));
                            }
                            else if (data.StartsWith("hex(b):")) //qword
                            {
                                /* Pourquoi le QWORD est-il stoqué sous la form de byte[] ?? */
                                byte[] b_val = ParseBinaryArray(data.Substring("hex(b):".Length), input);
                                ulong val = BitConverter.ToUInt64(b_val, 0);
                                last.Values[name] = new LocalRegistryValue(ValueType.QWORD,val);
                            }
                            else if (data.StartsWith("hex(2):")) // expandable string
                            {
                                string str = ParseString(data.Substring("hex(2):".Length), input);
                                last.Values[name] = new LocalRegistryValue(ValueType.ExpandableString,
                                    Encoding.Unicode.GetString(BytesFromString(str)));
                            }
                            else if (data.StartsWith("hex(7):")) // multi-string
                            {
                                string str = ParseString(data.Substring("hex(7):".Length), input);
                                last.Values[name] = new LocalRegistryValue(ValueType.MultiString,
                                    (string[])ParseMultiString(str));
                            }
                            else // string
                            {
                                last.Values[name] = new LocalRegistryValue(ValueType.String,
                                    (string)ArrangeString(ParseString(data.Substring(1, data.Length - 2), input)));
                            }
                        }
                    }
                }
            }
     
            private static string ArrangeString(string p)
            {
                string res = "";
     
                int actual = 0;
     
                using (StringReader reader = new StringReader(p))
                {
                    while (true)
                    {
                        actual = reader.Read();
                        if (actual < 0)
                            break;
                        else
                        {
                            char c = (char)actual;
                            if (c == '\\') /* échappement */
                            {
                                int escape = reader.Read();
                                if (escape < 0)
                                    throw new InvalidDataException("Séquence d'échappement invalide : fin du flux rencontré pour la ligne : " + p);
                                else
                                {
                                    char e = (char)escape;
                                    switch (e)
                                    {
                                        case 'n': { res += "\n"; break; }
                                        case 'r': { res += "\r"; break; }
                                        case '\\': { res += "\\"; break; }
                                        case '0': { res += "\0"; break; }
                                        case '\"': { res += "\""; break; }
                                        case '\'': { res += "\'"; break; }
                                        default:
                                            throw new InvalidDataException(String.Format("Séquence d'échappement non reconnue, {0}, à la ligne {1}", c.ToString() + e.ToString(), p));
                                    }
                                }
                            }
                            else
                            {
                                res += c.ToString();
                            }
                        }
                    }
                }
     
                return res;
            }
     
            private static string[] ParseMultiString(string str)
            {
                if (String.IsNullOrEmpty(str))
                    return new string[0];
                else
                {
                    str = Encoding.Unicode.GetString(BytesFromString(str));
     
                    return str.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
                }
            }
     
            private static byte[] BytesFromString(string p)
            {
                string[] parts = p.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                byte[] res = new byte[parts.Length];
     
                for (int i = 0; i < parts.Length; i++)
                {
                    res[i] = byte.Parse(parts[i], System.Globalization.NumberStyles.HexNumber);
                }
     
                return res;
            }
     
            private static string ParseString(string p, StreamReader input)
            {
                return ReadFullString(p, input);
            }
     
            private static uint ParseDword(string p, StreamReader input)
            {
                return uint.Parse(p, System.Globalization.NumberStyles.HexNumber);
            }
     
            private static byte[] ParseBinaryArray(string p, StreamReader input)
            {
                return BytesFromString(ReadFullString(p, input));
            }
     
            private static string ReadFullString(string p, StreamReader input)
            {
                string s = "";
                bool do_next = false;
                do
                {
                    if (p.EndsWith("\\"))
                    {
                        s += p.Substring(0, p.Length - 1); ;
                        do_next = true;
                    }
                    else
                    {
                        s += p;
                        do_next = false;
                    }
     
                    if (do_next)
                    {
                        p = input.ReadLine();
                        p = p.Substring(2); /* 2 espaces au début de la ligne */
                    }
                }
                while (do_next);
     
                return s;
            }
        }
    }

    Exemple d'utilisation, un dump :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    private void button1_Click(object sender, EventArgs e)
            {
                OpenFileDialog m = new OpenFileDialog();
                if (m.ShowDialog() == DialogResult.OK)
                {
                    using (FileStream fs = new FileStream(m.FileName, FileMode.Open, FileAccess.Read))
                    {
                        using (StreamReader rd = new StreamReader(fs, true))
                        {
                            var ts = RegFileImporter.ProcessRegistryFile(rd);
                            DumpTree(ts);
                        }
                    }
                }
            }
     
    private void DumpTree(LocalRegistryKey ts)
            {
                Trace.WriteLine(ts.Name);
                if (!ts.GlobalRoot)
                {
                    foreach (var item in ts.Values)
                    {
                        if (item.Value.ValueType == DreamShield.Deployment.Utils.ValueType.Binary)
                        {
                            Trace.WriteLine(String.IsNullOrEmpty(item.Key) ? "(Default)" : item.Key);
                            Trace.Indent();
                            byte[] val = (byte[])item.Value.Value;
                            for (int i = 0; i < val.Length; i++)
                            {
                                Trace.Write(val[i].ToString("X") + ",");
                            }
                            Trace.WriteLine("");
                            Trace.Unindent();
                        }
                        else if (item.Value.ValueType == DreamShield.Deployment.Utils.ValueType.MultiString)
                        {
                            Trace.WriteLine(String.IsNullOrEmpty(item.Key) ? "(Default)" : item.Key);
                            Trace.Indent();
                            string[] val = (string[])item.Value.Value;
                            for (int i = 0; i < val.Length; i++)
                            {
                                Trace.Write(val[i] + " | ");
                            }
                            Trace.WriteLine("");
                            Trace.Unindent();
                        }
                        else
                        {
                            Trace.WriteLine(String.Format("-{0}:{1}", String.IsNullOrEmpty(item.Key) ? "(Default)" : item.Key, item.Value));
                        }
                    }
                }
     
                Trace.Indent();
                foreach (var item in ts.SubKeys)
                {
                    DumpTree(item);
                }
                Trace.Unindent();
            }

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Bien, ça a le mérite d'exister maintenant. Un code à garder sous la main.

    J'ai fait un petit test rapide, premier essai, premier plantage. Une valeur de type DWORD codé ainsi ne passe pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "ProcessImageColumnWidth"=dword:000000c8
    C'est pas bien méchant, je pense, une histoire d'hexa à gérer. En VB je saurais faire, mais en C# je suis pas encore assez à l'aise.
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  3. #3
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Alala ... il était tard j'ai pas fait suffisamment de tests. Je corrige et je reviens.

  4. #4
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Voilà, j'ai modifié le premier message avec le nouveau code, et je l'ai testé sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Windows Registry Editor Version 5.00
     
    [HKEY_LOCAL_MACHINE\SOFTWARE\X\Test]
    "Test"="Test"
    "TestBin"=hex:4a,65,20,73,75,69,73,20,75,6e,20,70,65,74,69,74,20,63,68,61,74,\
      20,71,75,69,20,61,69,6d,65,20,62,69,65,6e,20,73,65,20,72,6f,75,6c,65,72,20,\
      70,61,72,20,74,65,72,72,65
    "TestDWord"=dword:000007c6
    "TestQWord"=hex(b):c6,07,00,00,00,00,00,00
    "TestMulti"=hex(7):4a,00,65,00,20,00,73,00,75,00,69,00,73,00,00,00,55,00,6e,00,\
      20,00,70,00,65,00,74,00,69,00,74,00,00,00,63,00,68,00,61,00,74,00,00,00,00,\
      00
    "TestExp"=hex(2):25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,\
      6c,00,65,00,73,00,25,00,5c,00,4c,00,6f,00,6c,00,00,00
    Et ça a marché nikel, donc ça devrais aller.

    Sinon pour la conversion en VB ça donne ça (pas testé):
    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
     
    Imports System
    Imports System.Collections.Generic
    Imports System.Text
    Imports System.IO
    Imports System.Data
     
    Namespace DreamShield.Deployment.Utils
        ''' <summary>
        ''' Classe qui permet de représenter les clefs du registre.
        ''' Partout où une variable name est utilisée, il s'agit d'un chemin
        ''' au sens du registre qui peut être HKEY_LOCAL_MACHINE\Microsoft\Windows
        ''' ou encore CurrentVersion\Uninstall.
        ''' </summary>
        Public Class LocalRegistryKey
            #Region "Constants"
     
            Public Const HKLM As String = "HKEY_LOCAL_MACHINE"
            Public Const HKCU As String = "HKEY_CURRENT_USER"
            Public Const HKCR As String = "HKEY_CLASSES_ROOT"
            Public Const HKU As String = "HKEY_USERS"
     
            #End Region
     
            #Region "Creation"
     
            ''' <summary>
            ''' Crée un nouvel objet de registre.
            ''' La clef renvoyée est un "parent virtuel" qui contient les clefs
            ''' HKLM, HKCU, HKCR et HKU
            ''' </summary>
            ''' <returns></returns>
            Public Shared Function CreateRepository() As LocalRegistryKey
                Dim res As New LocalRegistryKey(Nothing, Nothing)
                res.Childs.AddRange(New LocalRegistryKey() {New LocalRegistryKey(Nothing, HKLM), New LocalRegistryKey(Nothing, HKCU), New LocalRegistryKey(Nothing, HKCR), New LocalRegistryKey(Nothing, HKU)})
                res.GlobalRoot = True
     
                Return res
            End Function
     
            #End Region
     
            #Region "Globals & Constructor"
     
            ''' <summary>
            ''' Clef parente, null pour les clefs racines
            ''' </summary>
    Private _Parent As LocalRegistryKey
            Public Overridable Property Parent() As LocalRegistryKey
                Get
                    Return _Parent
                End Get
                Protected Set(ByVal value As LocalRegistryKey)
                    _Parent = value
                End Set
            End Property
     
    Private _Childs As List(Of LocalRegistryKey)
            Protected Property Childs() As List(Of LocalRegistryKey)
                Get
                    Return _Childs
                End Get
                Private Set(ByVal value As List(Of LocalRegistryKey))
                    _Childs = value
                End Set
            End Property
     
            ''' <summary>
            ''' Clefs enfantes
            ''' </summary>
            Public Overridable ReadOnly Property SubKeys() As LocalRegistryKey()
                Get
                    Return Childs.ToArray()
                End Get
            End Property
     
            Private Sub New(ByVal parent__1 As LocalRegistryKey, ByVal name As String)
                If parent__1 IsNot Nothing AndAlso [String].IsNullOrEmpty(name) Then
                    Throw New ArgumentNullException("name")
                End If
     
                GlobalRoot = False
                Parent = parent__1
                _name = name
     
                Childs = New List(Of LocalRegistryKey)()
     
                If Not GlobalRoot Then
                    InitRegValues()
                End If
            End Sub
     
            #End Region
     
            #Region "Access"
     
            ''' <summary>
            ''' Indique si cette clef est le parent virtuel des clefs racines
            ''' </summary>
    Private _GlobalRoot As Boolean
            Public Overridable Property GlobalRoot() As Boolean
                Get
                    Return _GlobalRoot
                End Get
                Protected Set(ByVal value As Boolean)
                    _GlobalRoot = value
                End Set
            End Property
     
            ''' <summary>
            ''' Indique si la clef actuelle est une racine
            ''' </summary>
            Public Overridable ReadOnly Property IsRoot() As Boolean
                Get
                    Return Parent Is Nothing
                End Get
            End Property
     
            Private _name As String = Nothing
     
            ''' <summary>
            ''' Nom de la clef. Il ne peut être modifié que pour les clefs non racines
            ''' </summary>
            Public Overridable Property Name() As String
                Get
                    Return _name
                End Get
                Set(ByVal value As String)
                    If IsRoot Then
                        Throw New InvalidOperationException("Impossible de renommer une racine")
                    Else
                        If [String].IsNullOrEmpty(value) Then
                            Throw New ArgumentNullException("value")
                        ElseIf [String].Equals(_name, value, StringComparison.OrdinalIgnoreCase) Then
                            _name = value
                        Else
                            If Parent.KeyExists(value) Then
                                Throw New DuplicateNameException(value)
                            Else
                                _name = value
                            End If
                        End If
                    End If
                End Set
            End Property
     
            ''' <summary>
            ''' Indique si la clef spécifiée existe
            ''' </summary>
            ''' <param name="name"></param>
            ''' <returns></returns>
            Public Overridable Function KeyExists(ByVal name As String) As Boolean
                Dim key As LocalRegistryKey = Nothing
                Return TryGetKey(name, key)
            End Function
     
            ''' <summary>
            ''' Obtients une clef (exception si elle n'existe pas)
            ''' </summary>
            ''' <param name="name"></param>
            ''' <returns></returns>
            Public Overridable Function Key(ByVal name As String) As LocalRegistryKey
                Return Key(name, False)
            End Function
     
            ''' <summary>
            ''' Charge la clef en la créant si elle n'existe pas et que canCreate vaut true.
            ''' </summary>
            ''' <remarks>Aucune clef ne peut être crée au même niveau que les clefs racines</remarks>
            ''' <param name="name"></param>
            ''' <param name="canCreate">Indique si la clef doit être crée si elle n'existe pas</param>
            ''' <returns></returns>
            Public Overridable Function Key(ByVal name As String, ByVal canCreate As Boolean) As LocalRegistryKey
                Dim key As LocalRegistryKey = Nothing
                If TryGetKey(name, key, canCreate) Then
                    Return key
                Else
                    Throw New KeyNotFoundException(name)
                End If
            End Function
     
            ''' <summary>
            ''' Tente d'obtenir la clef spécifiée et la renvoi si elle existe, ou renvoi
            ''' nul sinon dans key
            ''' </summary>
            ''' <param name="name"></param>
            ''' <param name="key"></param>
            ''' <returns></returns>
            Public Overridable Function TryGetKey(ByVal name As String, ByRef key As LocalRegistryKey) As Boolean
                Return TryGetKey(name, key, False)
            End Function
     
            Protected Overridable Function TryGetKey(ByVal name As String, ByRef key As LocalRegistryKey, ByVal canCreate As Boolean) As Boolean
                If [String].IsNullOrEmpty(name) Then
                    Throw New ArgumentNullException("value")
                End If
     
                Dim secs As String() = name.Split(New Char() {"\"c}, StringSplitOptions.RemoveEmptyEntries)
     
                key = Me
     
                For i As Integer = 0 To secs.Length - 1
                    key = FindKey(key, secs(i), canCreate)
                    If key Is Nothing Then
                        Exit For
                    End If
                Next
     
                Return key IsNot Nothing
            End Function
     
            Protected Overridable Function FindKey(ByVal key As LocalRegistryKey, ByVal name As String, ByVal canCreate As Boolean) As LocalRegistryKey
                If [String].IsNullOrEmpty(name) Then
                    Throw New ArgumentNullException("name")
                End If
                If name.Contains("]") OrElse name.Contains("[") Then
                    Throw New InvalidDataException("Nom invalide :" & name)
                End If
     
                For Each item In key.Childs
                    If item.Name IsNot Nothing AndAlso item.Name.Equals(name, StringComparison.OrdinalIgnoreCase) Then
                        Return item
                    End If
                Next
     
                If canCreate Then
                    If key.GlobalRoot Then
                        ' Impossible de créer une clef racine 
     
                        Return Nothing
                    Else
                        Dim n_key As New LocalRegistryKey(key, name)
                        key.Childs.Add(n_key)
                        Return n_key
                    End If
                Else
                    Return Nothing
                End If
            End Function
     
            #End Region
     
            #Region "Utils"
     
            ''' <summary>
            ''' Efface tous le contenu des clefs
            ''' </summary>
            ''' <remarks>Ne peut pas être appelé sur la racine virtuelle</remarks>
            Public Overridable Sub Clear()
                If GlobalRoot Then
                    Throw New InvalidOperationException("Impossible de supprimer les clefs racines")
                Else
                    Childs.Clear()
                    Values.Clear()
                End If
            End Sub
     
            ''' <summary>
            ''' Supprime la clef
            ''' </summary>
            ''' <remarks>Une clef racine ne peut pas être supprimée.</remarks>
            Public Overridable Sub Delete()
                If IsRoot Then
                    Throw New InvalidOperationException("Impossible de supprimer une racine")
                Else
                    Parent.Childs.Remove(Me)
     
                    Childs.Clear()
                    If Values IsNot Nothing Then
                        Values.Clear()
                    End If
     
                    Values = Nothing
                    Childs = Nothing
                    Parent = Nothing
                    _name = Nothing
                End If
            End Sub
     
            ''' <summary>
            ''' Obtient le nom complet de la clef
            ''' </summary>
            Public Overridable ReadOnly Property FullName() As String
                Get
                    Return (If(Parent IsNot Nothing, Parent.FullName & "\", "")) + Name
                End Get
            End Property
     
            Public Overloads Overrides Function ToString() As String
                Dim s As String = FullName
                Return If([String].IsNullOrEmpty(s), MyBase.ToString(), s)
            End Function
     
            #End Region
     
            #Region "Values"
     
            ''' <summary>
            ''' Liste des valeurs.
            ''' Pour la valeur par défaut, utiliser comme clef "" (la chaine vide), null étant une valeur
            ''' de clef interdite
            ''' </summary>
    Private _Values As Dictionary(Of String, LocalRegistryValue)
            Public Overridable Property Values() As Dictionary(Of String, LocalRegistryValue)
                Get
                    Return _Values
                End Get
                Protected Set(ByVal value As Dictionary(Of String, LocalRegistryValue))
                    _Values = value
                End Set
            End Property
     
            Protected Shared RegValueKeysComparerInstance As New RegValueKeysComparer()
     
            Protected Sub InitRegValues()
                Values = New Dictionary(Of String, LocalRegistryValue)(RegValueKeysComparerInstance)
            End Sub
     
            ' Juste par sécurité 
     
            Protected Class RegValueKeysComparer
                Implements IEqualityComparer(Of String)
                #Region "IEqualityComparer Membres"
     
                Public Overridable Function Equals(ByVal x As String, ByVal y As String) As Boolean
                    If [String].IsNullOrEmpty(x) Then
                        Return [String].IsNullOrEmpty(y)
                    Else
                        Return [String].Equals(x, y, StringComparison.OrdinalIgnoreCase)
                    End If
                End Function
     
                Public Overridable Function GetHashCode(ByVal obj As String) As Integer
                    Return If(obj Is Nothing, 0, obj.GetHashCode())
                End Function
            End Class
     
            #End Region
        End Class
     
        #End Region
     
        Public Class LocalRegistryValue
            Public Sub New(ByVal vType As ValueType, ByVal vVal As Object)
                ValueType = vType
                Value = vVal
            End Sub
     
            Protected m_valueType As ValueType = ValueType.Binary
     
            ''' <summary>
            ''' Type de valeur
            ''' </summary>
            ''' <remarks>Changer de type efface automatiquement la variable Value</remarks>
            Public Overridable Property ValueType() As ValueType
                Get
                    Return m_valueType
                End Get
                Set(ByVal value As ValueType)
                    If m_valueType <> value Then
                        m_valueType = value
                        _value = Nothing
                    End If
                End Set
            End Property
     
            Protected _value As Object = Nothing
     
            ''' <summary>
            ''' Valeur, doit être convertible en ValueType
            ''' </summary>
            Public Overridable Property Value() As Object
                Get
                    Return _value
                End Get
                Set(ByVal value As Object)
                    If Not CheckValue(ValueType, value) Then
                        Throw New InvalidDataException([String].Format("L'argument {0} n'est pas convertible en {1}", value, ValueType))
                    Else
                        _value = value
                    End If
                End Set
            End Property
     
            Protected Overridable Function CheckValue(ByVal ValueType As ValueType, ByVal value As Object) As Boolean
                If value Is Nothing Then
                    Return True
                Else
                    Select Case ValueType
                        Case ValueType.Binary
                            If True Then
                                Return GetType(Byte()).IsAssignableFrom(value.[GetType]())
                            End If
                        Case ValueType.DWORD
                            If True Then
                                Return GetType(UInteger).IsAssignableFrom(value.[GetType]())
                            End If
                        Case ValueType.QWORD
                            If True Then
                                Return GetType(ULong).IsAssignableFrom(value.[GetType]())
                            End If
                        Case ValueType.MultiString
                            If True Then
                                Return GetType(String()).IsAssignableFrom(value.[GetType]())
                            End If
                        Case ValueType.ExpandableString, ValueType.[String]
                            If True Then
                                Return GetType(String).IsAssignableFrom(value.[GetType]())
                            End If
                        Case Else
                            If True Then
                                Return False
                            End If
                    End Select
                End If
            End Function
     
            Public Overloads Overrides Function ToString() As String
                Return [String].Format("{0}", Value)
            End Function
        End Class
     
        Public Enum ValueType
            ''' <summary>
            ''' Binary registry value type : convertit en byte[]
            ''' </summary>
            Binary
            ''' <summary>
            ''' DWORD registry value type : convertit en uint
            ''' </summary>
            DWORD
            ''' <summary>
            ''' QWORD registry value type : convertit en ulong
            ''' </summary>
            QWORD
            ''' <summary>
            ''' Expandable string registry value type : convertit en string
            ''' </summary>
            ExpandableString
            ''' <summary>
            ''' MultiString registry value type : convertit en string[]
            ''' </summary>
            MultiString
            ''' <summary>
            ''' String registry value type : convertit en string
            ''' </summary>
            [String]
        End Enum
     
        Public Module RegFileImporter
            Private Sub New()
            End Sub
            Public Function ProcessRegistryFile(ByVal input As StreamReader) As LocalRegistryKey
                Return ProcessRegistryFile(input, Nothing)
            End Function
     
            Public Function ProcessRegistryFile(ByVal input As StreamReader, ByVal result As LocalRegistryKey) As LocalRegistryKey
                If result Is Nothing Then
                    result = LocalRegistryKey.CreateRepository()
                End If
     
                Dim last As LocalRegistryKey = Nothing
     
                Dim current_line As String = ""
                While Not input.EndOfStream
                    current_line = input.ReadLine()
                    If current_line.StartsWith("[") Then
                        ' section 
     
                        Dim [end] As Integer = current_line.IndexOf("]")
                        If [end] < 1 Then
                            Throw New InvalidDataException("Ligne invalide :" & current_line)
                        Else
                            Dim key_name As String = current_line.Substring(1, [end] - 1)
     
                            last = result.Key(key_name, True)
                        End If
                    ElseIf current_line.StartsWith("@") Then
                        ' valeur par défaut 
     
                        ReadValue(current_line, input, last)
                    ElseIf current_line.StartsWith("""") Then
                        ' valeur nommée 
     
                        ReadValue(current_line, input, last)
                    End If
                End While
     
                Return result
            End Function
     
            Private Sub ReadValue(ByVal current_line As String, ByVal input As StreamReader, ByVal last As LocalRegistryKey)
                If [String].IsNullOrEmpty(current_line) Then
                    Exit Sub
                Else
                    Dim secs As String() = current_line.Split(New Char() {"="c}, 2)
                    If secs.Length <> 2 Then
                        Throw New InvalidDataException("Ligne invalide :" & current_line)
                    Else
                        Dim name As String = secs(0)
                        Dim data As String = secs(1)
     
                        If name = "@" Then
                            name = ""
                        Else
                            name = name.Substring(1, name.Length - 2)
                        End If
                        ' On retire les quotes 
     
                        If [String].IsNullOrEmpty(data) OrElse data = """""" Then
                            last.Values(name) = New LocalRegistryValue(ValueType.[String], Nothing)
                        Else
                            If data.StartsWith("hex:") Then
                                ' binary
                                last.Values(name) = New LocalRegistryValue(ValueType.Binary, DirectCast(ParseBinaryArray(data.Substring("hex:".Length), input), Byte()))
                            ElseIf data.StartsWith("dword:") Then
                                'dword
                                last.Values(name) = New LocalRegistryValue(ValueType.DWORD, CUInt(ParseDword(data.Substring("dword:".Length), input)))
                            ElseIf data.StartsWith("hex(b):") Then
                                'qword
                                ' Pourquoi le QWORD est-il stoqué sous la form de byte[] ?? 
     
                                Dim b_val As Byte() = ParseBinaryArray(data.Substring("hex(b):".Length), input)
                                Dim val As ULong = BitConverter.ToUInt64(b_val, 0)
                                last.Values(name) = New LocalRegistryValue(ValueType.QWORD, val)
                            ElseIf data.StartsWith("hex(2):") Then
                                ' expandable string
                                Dim str As String = ParseString(data.Substring("hex(2):".Length), input)
                                last.Values(name) = New LocalRegistryValue(ValueType.ExpandableString, Encoding.Unicode.GetString(BytesFromString(str)))
                            ElseIf data.StartsWith("hex(7):") Then
                                ' multi-string
                                Dim str As String = ParseString(data.Substring("hex(7):".Length), input)
                                last.Values(name) = New LocalRegistryValue(ValueType.MultiString, DirectCast(ParseMultiString(str), String()))
                            Else
                                ' string
                                last.Values(name) = New LocalRegistryValue(ValueType.[String], DirectCast(ArrangeString(ParseString(data.Substring(1, data.Length - 2), input)), String))
                            End If
                        End If
                    End If
                End If
            End Sub
     
            Private Function ArrangeString(ByVal p As String) As String
                Dim res As String = ""
     
                Dim actual As Integer = 0
     
                Using reader As New StringReader(p)
                    While True
                        actual = reader.Read()
                        If actual < 0 Then
                            Exit While
                        Else
                            Dim c As Char = CChar(actual)
                            If c = "\"c Then
                                ' échappement 
                                Dim escape As Integer = reader.Read()
                                If escape < 0 Then
                                    Throw New InvalidDataException("Séquence d'échappement invalide : fin du flux rencontré pour la ligne : " & p)
                                Else
                                    Dim e As Char = CChar(escape)
                                    Select Case e
                                        Case "n"c
                                            If True Then
                                                res += vbLf
                                                Exit Select
                                            End If
                                        Case "r"c
                                            If True Then
                                                res += vbCr
                                                Exit Select
                                            End If
                                        Case "\"c
                                            If True Then
                                                res += "\"
                                                Exit Select
                                            End If
                                        Case "0"c
                                            If True Then
                                                res += vbNullChar
                                                Exit Select
                                            End If
                                        Case """"c
                                            If True Then
                                                res += """"
                                                Exit Select
                                            End If
                                        Case "'"c
                                            If True Then
                                                res += "'"
                                                Exit Select
                                            End If
                                        Case Else
                                            Throw New InvalidDataException([String].Format("Séquence d'échappement non reconnue, {0}, à la ligne {1}", c.ToString() + e.ToString(), p))
                                    End Select
                                End If
                            Else
                                res += c.ToString()
                            End If
                        End If
                    End While
                End Using
     
                Return res
            End Function
     
            Private Function ParseMultiString(ByVal str As String) As String()
                If [String].IsNullOrEmpty(str) Then
                    Return New String(-1) {}
                Else
                    str = Encoding.Unicode.GetString(BytesFromString(str))
     
                    Return str.Split(New Char() {ControlChars.NullChar}, StringSplitOptions.RemoveEmptyEntries)
                End If
            End Function
     
            Private Function BytesFromString(ByVal p As String) As Byte()
                Dim parts As String() = p.Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
                Dim res As Byte() = New Byte(parts.Length - 1) {}
     
                For i As Integer = 0 To parts.Length - 1
                    res(i) = Byte.Parse(parts(i), System.Globalization.NumberStyles.HexNumber)
                Next
     
                Return res
            End Function
     
            Private Function ParseString(ByVal p As String, ByVal input As StreamReader) As String
                Return ReadFullString(p, input)
            End Function
     
            Private Function ParseDword(ByVal p As String, ByVal input As StreamReader) As UInteger
                Return UInteger.Parse(p, System.Globalization.NumberStyles.HexNumber)
            End Function
     
            Private Function ParseBinaryArray(ByVal p As String, ByVal input As StreamReader) As Byte()
                Return BytesFromString(ReadFullString(p, input))
            End Function
     
            Private Function ReadFullString(ByVal p As String, ByVal input As StreamReader) As String
                Dim s As String = ""
                Dim do_next As Boolean = False
                Do
                    If p.EndsWith("\") Then
                        s += p.Substring(0, p.Length - 1)
     
     
                        do_next = True
                    Else
                        s += p
                        do_next = False
                    End If
     
                    If do_next Then
                        p = input.ReadLine()
                        p = p.Substring(2)
                        ' 2 espaces au début de la ligne 
                    End If
                Loop While do_next
     
                Return s
            End Function
        End Module
    End Namespace
    et
    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim m As New OpenFileDialog()
        If m.ShowDialog() = DialogResult.OK Then
            Using fs As New FileStream(m.FileName, FileMode.Open, FileAccess.Read)
                Using rd As New StreamReader(fs, True)
                    Dim ts = RegFileImporter.ProcessRegistryFile(rd)
                    DumpTree(ts)
                End Using
            End Using
        End If
    End Sub
     
    Private Sub DumpTree(ByVal ts As LocalRegistryKey)
        Trace.WriteLine(ts.Name)
        If Not ts.GlobalRoot Then
            For Each item In ts.Values
                If item.Value.ValueType = DreamShield.Deployment.Utils.ValueType.Binary Then
                    Trace.WriteLine(If([String].IsNullOrEmpty(item.Key), "(Default)", item.Key))
                    Trace.Indent()
                    Dim val As Byte() = DirectCast(item.Value.Value, Byte())
                    For i As Integer = 0 To val.Length - 1
                        Trace.Write(val(i).ToString("X") & ",")
                    Next
                    Trace.WriteLine("")
                    Trace.Unindent()
                ElseIf item.Value.ValueType = DreamShield.Deployment.Utils.ValueType.MultiString Then
                    Trace.WriteLine(If([String].IsNullOrEmpty(item.Key), "(Default)", item.Key))
                    Trace.Indent()
                    Dim val As String() = DirectCast(item.Value.Value, String())
                    For i As Integer = 0 To val.Length - 1
                        Trace.Write(val(i) & " | ")
                    Next
                    Trace.WriteLine("")
                    Trace.Unindent()
                Else
                    Trace.WriteLine([String].Format("-{0}:{1}", If([String].IsNullOrEmpty(item.Key), "(Default)", item.Key), item.Value))
                End If
            Next
        End If
     
        Trace.Indent()
        For Each item In ts.SubKeys
            DumpTree(item)
        Next
        Trace.Unindent()
    End Sub

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Points : 1 148
    Points
    1 148
    Par défaut
    Excellent !
    Peut être faudrait il préparer un bibliothèque C# made in developpez.com ?
    Neilos

  6. #6
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Il n'y a pas de tel projet actuellement dans la section.
    Mais on peut s'en sortir avec ça : http://dotnet.developpez.com/sources/

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Points : 1 148
    Points
    1 148
    Par défaut
    Oui mais ça pourrait être un bon projet !
    Neilos

  8. #8
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    ça veux dire que tu te proposes pour la créer ?

  9. #9
    Membre éprouvé

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Points : 1 148
    Points
    1 148
    Par défaut
    Y participer dans tous les cas je pense.
    La créer, je ne sais pas si j'aurais assez de temps mais ça pourrait être intéressant non ?
    Neilos

Discussions similaires

  1. Parseur de fichier .reg
    Par smyley dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 11/01/2009, 04h16
  2. Parseur de fichier de configuration
    Par snyff dans le forum Windows
    Réponses: 4
    Dernier message: 15/06/2006, 14h54
  3. Fichier .reg
    Par bilb0t dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 14/04/2006, 09h34
  4. fichier .reg
    Par cubepiege dans le forum Windows
    Réponses: 5
    Dernier message: 11/08/2005, 18h22
  5. parseur de fichier
    Par ronan99999 dans le forum C
    Réponses: 10
    Dernier message: 10/02/2004, 12h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo