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

 Delphi Discussion :

[D7] [Windows 10] Lecture du registre


Sujet :

Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut [D7] [Windows 10] Lecture du registre
    Bonjour,

    j'essaye de lire la valeur d'une clef de type DWord sous forme d'entier par ceci :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    { ========================================================================== }
    Function TF_Princ.GetValeurClef(Nom : String): String;
    Var
      Registre : TRegistry ;
      Nombre : Integer ;
      CleInfosWindows : String ;
    Begin
      Result := 'Echec de lecture' ;
      CleInfosWindows := '\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ;
      Registre := TRegistry.Create;
      Registre.RootKey := HKEY_LOCAL_MACHINE;
      Registre.OpenKeyReadOnly(CleInfosWindows);
      try
         Nombre := Registre.ReadInteger(Nom);
         Result := IntToStr(Nombre) ;
      Except
        ShowMessage('Erreur de lecture du registre') ;
      End ;
      Registre.CloseKey;
      Registre.Free;
    End ;
    { ========================================================================== }
    procedure TF_Princ.Button4Click(Sender: TObject);
    begin
      ShowMessage('Valeur de la Clef : '+GetValeurClef('InstallDate') ) ;
    end;
    { ========================================================================== }
    ça ne plante pas, mais cela renvoie 0 au lieu de 1568616847 ou 5d7f318f (chez moi !)

    Comment lire correctement une clef de type Dword ?

    Merci

    A+
    Charly

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 097
    Points : 41 081
    Points
    41 081
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Je ne travaille plus avec les registres depuis l'apparition de l'UAC (c'est dire que ça date pas d'hier) du coup, ta question, m'a interpellée et j'ai voulu faire quelques tests.

    Effectivement, ton code me renvoie la valeur 0 j'ai même utilisé quelques versions différentes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    nombre : string;
     
         if registre.ValueExists('InstallDate')
           then nombre:=Registre.GetDataAsString('InstallDate',true)
           else nombre:='valeur inexistante !';
    avec les mêmes résultats (mais confirmation du type) et pourtant, la valeur existe dword:00000000 alors qu'avec mon éditeur de registre je lis 5d30884f

    Du coup je me suis posé la question "sécurité", un test sur une valeur DWord quelconque dans HKEY_LOCAL_USER m'a conforté : cela ne vient pas du code puisque, dans cette clé les valeurs retournées sont "correctes".
    Mais, Demande d'élévation de droits dans le manifeste, changement de mode d'ouverture (Open plutôt qu'OpenReadonly) , exécution en tant qu'administrateur (hors ide) rien n'y fait M

    Du coup j'ai testé différemment , un petit mémo pour montrer les valeurs et
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    procedure TForm63.Button1Click(Sender: TObject);
    Var
      Registre : TRegistry ;
      resultat : string ;
      Liste : TStringList;
      valeur : String;
      CleInfosWindows : String ;
    Begin
      CleInfosWindows := 'SOFTWARE\Microsoft\Windows NT\CurrentVersion';
      Registre := TRegistry.Create;
      Registre.RootKey := HKEY_LOCAL_MACHINE;
      Registre.OpenKeyReadOnly(CleInfosWindows);
      Liste:= TStringList.Create;
      try
         Registre.GetValueNames(Liste);
         for valeur in Liste do
          begin
           if registre.ValueExists(valeur)
             then resultat:=Registre.GetDataAsString(valeur,true)
             else resultat:=' inexistante !';  // normalement impossible 
         Memo1.Lines.Add(Valeur+' = '+resultat);
         end;
      finally
        Liste.Free;
      end;
      Registre.CloseKey;
      Registre.Free;
    end;

    BaseBuildRevisionNumber = dword:000000EF
    BuildBranch = 19h1_release_svc_prod1
    BuildGUID = ffffffff-ffff-ffff-ffff-ffffffffffff
    BuildLab = 18362.19h1_release_svc_prod1.190628-1641
    BuildLabEx = 18362.239.x86fre.19h1_release_svc_prod1.190628-1641
    CompositionEditionID = Core
    CurrentBuild = 18362
    CurrentBuildNumber = 18362
    CurrentMajorVersionNumber = dword:0000000A
    CurrentMinorVersionNumber = dword:00000000
    CurrentType = Multiprocessor Free
    CurrentVersion = 6.3
    EditionID = Core
    EditionSubManufacturer =
    EditionSubstring =
    EditionSubVersion =
    InstallationType = Client
    InstallDate = dword:00000000
    ProductName = Windows 10 Home
    ReleaseId = 1903
    SoftwareType = System
    SystemRoot = C:\WINDOWS
    UBR = dword:000001A2
    cette fichue InstallDate persiste et signe alors que Label1.Caption:=IntTostr(Registre.ReadInteger('CurrentMajorVersionNumber')); me renvoie bien un chiffre (10)
    MS nous ferait-il des cachotteries ?

  3. #3
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Merci Serge de t'être penché sur le problème.

    J'ai essayé de lire cette clef en binaire. Même constat avec un Array[0..3] of byte : cela renvoie 0 0 0 0

    Pourtant un export de la clef donne bien la bonne valeur. Je pourrai donc peut être exporter dans un fichier txt et rechercher la bonne valeur dans ce fichier.

    Il y a une rubrique "Comment sauvegarder la base de registre" dans la FAQ. Mais je vais chercher comment sauvegarder seulement une clef sinon le fichier va être très volumineux ?

    A+
    Charly

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 097
    Points : 41 081
    Points
    41 081
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    Merci Serge de t'être penché sur le problème.
    de rien c'est le genre de chose qui me titille l'esprit
    J'ai essayé de lire cette clef en binaire. Même constat avec un Array[0..3] of byte : cela renvoie 0 0 0 0
    moi itou, plus étrange tu constateras dans mon report du mémo que la valeur InstallTime n'apparaît pas alors quelle existe !
    Pourtant un export de la clef donne bien la bonne valeur.
    je n'avais pas pensé à ça

    Sinon, s'il s'agit vraiment d'obtenir la date d'installation (voire des mises à jour) il y a toujours le marteau pilon WMI
    Code WQL : Sélectionner tout - Visualiser dans une fenêtre à part
    Select CurrentTimeZone,InstallDate from Win32_OperatingSystem
    voir aussi https://theroadtodelphi.com/2011/03/...i-wmi-and-wua/

  5. #5
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Cc Charly,

    Essai ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Registre := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY);
    Bye

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 097
    Points : 41 081
    Points
    41 081
    Billets dans le blog
    62
    Par défaut
    Buzz, plus loin et au delà !
    Effectivement TRegistry.Create(KEY_WOW64_64KEY); // j'ai ôté le KEY_WRITE me renvoie bien plus de valeurs
    dont InstallDate = dword:5D30884F
    et même InstallTime = hex:29,95,70,CC,78,3D,D5,01 qui apparaît dans la liste des valeurs

    à noter que les date sont au format unix donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       label1.Caption := FormatDateTime('dd/mm/yyyy',unixtoDateTime(Registre.ReadInteger('InstallDate'),true));

  7. #7
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Buzz, plus loin et au delà !
    Lool

    TRegistry.Create(KEY_WOW64_64KEY); // j'ai ôté le KEY_WRITE me renvoie bien plus de valeurs

    Ouais mais cela permet de voir qu'on peut a plusieurs choix c'est pour cela que je l’avais laissé.

    Je retourne dans l'espace...

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Hélas ! rien à faire chez moi, cela renvoie toujours 0 ?

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    { ========================================================================== }
    procedure TF_Princ.Button4Click(Sender: TObject);
    begin
      ShowMessage('Valeur de la Clef : '+GetValeurClef('InstallDate') ) ;
    end;
    { ========================================================================== }
    Function TF_Princ.GetValeurClef(Nom : String): String;
    Const
      KEY_WOW64_64KEY = $0100;
    Var
      Registre : TRegistry ;
      Nombre : Integer ;
      CleInfosWindows : String ;
    Begin
      Result := 'Echec de lecture' ;
      CleInfosWindows := '\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ;
      Registre := TRegistry.Create(KEY_WOW64_64KEY);
      Registre.RootKey := HKEY_LOCAL_MACHINE;
      Registre.OpenKeyReadOnly(CleInfosWindows);
      try
         Nombre := Registre.ReadInteger(Nom);
         Result := IntToStr(Nombre) ;
      Except
        ShowMessage('Erreur de lecture du registre') ;
      End ;
      Registre.CloseKey;
      Registre.Free;
    End ;
    { ========================================================================== }
    J'ai du déclarer la constante KEY_WOW64_64KEY car elle était inconnue de D7. Ce n'est peut être pas la bonne valeur ?

    A+
    Charly

    PS code exécuté en mode administrateur

  9. #9
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Si c'est bien 256 !!

    KEY_QUERY_VALUE = $0001;
    {$EXTERNALSYM KEY_QUERY_VALUE}
    KEY_SET_VALUE = $0002;
    {$EXTERNALSYM KEY_SET_VALUE}
    KEY_CREATE_SUB_KEY = $0004;
    {$EXTERNALSYM KEY_CREATE_SUB_KEY}
    KEY_ENUMERATE_SUB_KEYS = $0008;
    {$EXTERNALSYM KEY_ENUMERATE_SUB_KEYS}
    KEY_NOTIFY = $0010;
    {$EXTERNALSYM KEY_NOTIFY}
    KEY_CREATE_LINK = $0020;
    {$EXTERNALSYM KEY_CREATE_LINK}
    KEY_WOW64_32KEY = $0200;
    {$EXTERNALSYM KEY_WOW64_32KEY}
    KEY_WOW64_64KEY = $0100;
    {$EXTERNALSYM KEY_WOW64_64KEY}
    KEY_WOW64_RES = $0300;
    {$EXTERNALSYM KEY_WOW64_RES}
    Peut-être une autre valeur ?

    tu es sur une machine 64 bits ?

  10. #10
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Bonjour Buzz,
    oui, je suis sur une machine 64 bits.

    Mais j'y arrive avec ceci tiré du net :

    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
    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
      Function IsWin64: Boolean;
     
      Function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
        External 'Kernel32.dll' Name 'Wow64DisableWow64FsRedirection';
     
      Function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
        External 'Kernel32.dll' Name 'Wow64EnableWow64FsRedirection';
     
    var
      Wow64Redirection: LongBool;
    implementation
     
    Uses Registry, ShellAPI;
     
    { ========================================================================== }
    function IsWin64: Boolean;
    var
      IsWow64Process : function(hProcess : THandle; var Wow64Process : BOOL): BOOL; stdcall;
      Wow64Process : BOOL;
    begin
      Result := False;
      IsWow64Process := GetProcAddress(GetModuleHandle(Kernel32), 'IsWow64Process');
      if Assigned(IsWow64Process) then begin
        if IsWow64Process(GetCurrentProcess, Wow64Process) then begin
          Result := Wow64Process;
        end;
      end;
    end;
    { ========================================================================== }
    function DisableWowRedirection: Boolean;
    type
      TWow64DisableWow64FsRedirection = function(var Wow64FsEnableRedirection: 
    LongBool): LongBool; StdCall;
    Var
      hHandle: THandle;
      Wow64DisableWow64FsRedirection: TWow64DisableWow64FsRedirection;
    begin
      Result := true;
      if not IsWin64 then exit;
      try
        hHandle := GetModuleHandle('kernel32.dll');
        @Wow64DisableWow64FsRedirection := GetProcAddress(hHandle,'Wow64DisableWow64FsRedirection');
        if ((hHandle <> 0) and (@Wow64DisableWow64FsRedirection <> nil))
          then Wow64DisableWow64FsRedirection(Wow64Redirection);
      except
        result := false;
      end;
    end;
    { ========================================================================== }
    function RevertWowRedirection: Boolean;
    type
      TWow64RevertWow64FsRedirection  = function(var 
    Wow64RevertWow64FsRedirection: LongBool): LongBool; StdCall;
    var
      hHandle: THandle;
      Wow64RevertWow64FsRedirection: TWow64RevertWow64FsRedirection;
    begin
      Result := true;
      if not IsWin64 then exit;
      try
        hHandle := GetModuleHandle('kernel32.dll');
        @Wow64RevertWow64FsRedirection  := GetProcAddress(hHandle,'Wow64RevertWow64FsRedirection');
        if ((hHandle <> 0) and (@Wow64RevertWow64FsRedirection <> nil))
          then Wow64RevertWow64FsRedirection(Wow64Redirection);
      except
        result := false;
      end;
    end;
    { ================================================================================= }
    procedure TF_Princ.SauvegardeRegistre;
    // Sauvegarde d'une clef du registre dans un fichier txt
    var
      SEInfo: TShellExecuteInfo;
      Wow64FsEnableRedirection: LongBool;
    begin
      FillChar(SEInfo, SizeOf(SEInfo), 0);
      SEInfo.cbSize := SizeOf(TShellExecuteInfo);
     
      with SEInfo do
      begin
        fMask := SEE_MASK_NOCLOSEPROCESS;
        Wnd := Application.Handle;
        lpFile := PChar('cmd.exe');
        lpParameters :=
          PChar('/k REG.exe EXPORT "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" "D:\Delphi\Tests\Registre1.txt" /y');
          // "/k" -> la fenetre reste ouverte "/c" -> la fenetre de commande se referme automatiquement
        nShow := SW_SHOWNORMAL;
      end;
      Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection);
      ShellExecuteEx(@SEInfo);
      Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection);
    end;
    { ================================================================================= }
    procedure TF_Princ.Button5Click(Sender: TObject);
    begin
      SauvegardeRegistre ;
    end;
    { ================================================================================= }
    Cela me renvoie bien :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    Windows Registry Editor Version 5.00
     
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion]
    "SystemRoot"="C:\\WINDOWS""BaseBuildRevisionNumber"=dword:00000001
    "BuildBranch"="19h1_release"
    "BuildGUID"="ffffffff-ffff-ffff-ffff-ffffffffffff"
    "BuildLab"="18362.19h1_release.190318-1202"
    "BuildLabEx"="18362.1.amd64fre.19h1_release.190318-1202"
    "CompositionEditionID"="Core"
    "CurrentBuild"="18362"
    "CurrentBuildNumber"="18362"
    "CurrentMajorVersionNumber"=dword:0000000a
    "CurrentMinorVersionNumber"=dword:00000000
    "CurrentType"="Multiprocessor Free"
    "CurrentVersion"="6.3"
    "EditionID"="Core"
    "EditionSubManufacturer"=""
    "EditionSubstring"=""
    "EditionSubVersion"=""
    "InstallationType"="Client"
    "InstallDate"=dword:5d7f318f
    "ProductName"="Windows 10 Home"
    "ReleaseId"="1903"
    "SoftwareType"="System"
    "UBR"=dword:000001a2
    "PathName"="C:\\Windows"
    "ProductId"="00325-80000-00000-AAOEM"
    ...
    "InstallTime"=hex(b):05,5f,fa,88,5b,6c,d5,01
    Merci à tous les 2

    A+
    Charly

    PS : la méthode ReadKey ne fonctionne toujours pas chez moi ...

  11. #11
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 754
    Points : 13 340
    Points
    13 340
    Par défaut
    Le problème vient sans doute de OpenKeyReadOnly.

    OpenKeyReadOnly force le flag KEY_READ. Cela revient à redéfinir le mode d'accès choisi au Create (qui est par défaut en KEY_ALLACCESS).
    Les Delphi récents conservent les flags KEY_WOW64_xxKEY à l'appel de cette méthode mais ça ne doit pas être le cas sous D7 qui ne prévoyait pas encore le 64 bits.

    Passe par la méthode Open qui elle ne va pas écraser ce qui est défini au Create :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Registre := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
    Registre.RootKey := HKEY_LOCAL_MACHINE;
    Registre.Open(CleInfosWindows);

  12. #12
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Merci AndnotOr, je vais tester dès que j'ai un peu de temps et je reviens donner une solution qui fonctionne sous D7 !

    A+
    Charly

  13. #13
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 097
    Points : 41 081
    Points
    41 081
    Billets dans le blog
    62
    Par défaut
    Je n'avais pas réellement fait attention à D7
    Comme je n'ai pas D7 sur ce poste j'ai jonglé entre mon vieux pc (vista) et celui-ci

    TRegistry.Create(KEY_READ or KEY_WOW64_64KEY); ne fonctionne pas, cette histoire de redirection par contre me parait une bonne piste

  14. #14
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Merci Andnoror, cela fonctionne parfaitement (comme d'habitude !!)

    Voici le code complet qui fonctionne et me renvoie un entier à décoder :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    { ========================================================================== }
    procedure TF_Princ.Button4Click(Sender: TObject);
    begin
      ShowMessage('Valeur de la Clef : '+GetValeurClef('InstallDate') ) ;
    end;
    { ========================================================================== }
    Function TF_Princ.GetValeurClef(Nom : String): String;
    Const
      KEY_WOW64_64KEY = $0100;
    Var
      Registre : TRegistry ;
      Nombre : Integer ;
      CleInfosWindows : String ;
    Begin
      Result := 'Echec de lecture' ;
      CleInfosWindows := '\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ;
      Registre := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
      Registre.RootKey := HKEY_LOCAL_MACHINE;
      Registre.OpenKey(CleInfosWindows, False);
      try
         Nombre := Registre.ReadInteger(Nom);
         Result := IntToStr(Nombre) ;
      Except
        ShowMessage('Erreur de lecture du registre') ;
      End ;
      Registre.CloseKey;
      Registre.Free;
    End ;
    { ========================================================================== }
    Merci aussi à Sergio et Buzz (également ...)

    A+
    Charly

  15. #15
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 097
    Points : 41 081
    Points
    41 081
    Billets dans le blog
    62
    Par défaut
    Bonsoir,
    effectivement je m'étais planté dans mon test j'utilisais toujours Registre.OpenKeyReadOnly(CleInfosWindows) au lieu de Registre.OpenKey(CleInfosWindows, False);

  16. #16
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Bonjour,

    pour clore le sujet voici la version finale avec décodage de la date d'installation en clair :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    { ========================================================================== }
    Function TF_Princ.GetInstallDate: String;
    //   Recherche de la date de derniere installation de Windows
    Const
      KEY_WOW64_64KEY = $0100;   // n'existe pas en D7
    Var
      Registre        : TRegistry ;
      Nombre          : Int64 ;
      CleInfosWindows : String ;
      Nbj, Nbj2             : Integer ;
      DateUnix , DateDElphi : TDateTime ;
    Begin
      Result := 'Erreur de lecture de la date d''installation de Windows' ;
      CleInfosWindows := '\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ;
      Registre := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
      Registre.RootKey := HKEY_LOCAL_MACHINE;
      Registre.OpenKey(CleInfosWindows, False);
      try
         if Registre.ValueExists('InstallDate') then Nombre := Registre.ReadInteger('InstallDate');
     
         Nombre := Round(Nombre / 86400 );
         DateUnix := StrToDateTime('1/1/1970') ;
         DateDelphi := StrToDateTime('30/12/1899') ;
         Nbj2 := Daysbetween(DateUnix, DateDelphi) ;
         Nombre := Nombre + NbJ2 ;
         Result := DateTimeToStr(Nombre) ;
      Except
        ShowMessage('Erreur de lecture de la date d''installation de Windows') ;
      End ;
      Registre.CloseKey;
      Registre.Free;
    End ;
    { ========================================================================== }
    A+
    Charly

  17. #17
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 754
    Points : 13 340
    Points
    13 340
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    pour clore le sujet voici la version finale avec décodage de la date d'installation en clair :
    C'est trop compliqué et source d'exceptions.

    Ces conversions de dates fonctionnent peut-être sur ton poste si le séparateur est / et un format dd/mm/yyyy mais se planteront sur tout autre système. Il faudrait forcer le format de conversion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var
      FormatSettings :TFormatSettings;
     
    begin
      FormatSettings.DateSeparator   := '/';
      FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
     
      DateUnix := StrToDateTime('1/1/1970', FormatSettings);
    Mais tout cela est inutile puisque le décalage entre DelphiEpoch (30.12.1899) et UnixEpoch (1.01.1970) est connu : 25 569 jours. Autant déclarer une constante.

    De plus (chez moi) ta fonction par rapport à la commande PowerShell ([WMI]'').ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).InstallDate) est décalée d'un jour. Problème d'arrondi ou de calcul de dates.

    Enfin, puisque la date d'installation est un nombre de secondes depuis l'UnixEpoch, autant incrémenter les secondes (IncSecond)

    J'écrirais cela ainsi :
    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
    16
    17
    18
    function GetInstallDate: String;
    Const
      KEY_WOW64_64KEY = $0100;   // n'existe pas en D7
      UnixEpoch       = 25569;   // 1.01.1970
     
    Begin
      with TRegistry.Create(KEY_READ or KEY_WOW64_64KEY) do
      try
        RootKey := HKEY_LOCAL_MACHINE;
     
        if OpenKey('\SOFTWARE\Microsoft\Windows NT\CurrentVersion', False) and ValueExists('InstallDate')
        then Result := DateTimeToStr(Trunc(IncSecond(UnixEpoch, ReadInteger('InstallDate'))))
        else Result := 'Erreur de lecture de la date d''installation de Windows';
     
      finally
        Free;
      end;
    end;

  18. #18
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Merci Andnotor pour ce code beaucoup plus concis.

    Pour le format des dates tu as raison.

    Pour le décalage constant, je sais bien, mais je voulais le calculer car je ne le connaissais pas et je voulais décortiquer le calcul.

    Ton code est évidement bien meilleur.

    A+
    Charly

  19. #19
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 370
    Points : 3 144
    Points
    3 144
    Par défaut
    Andornot, juste pour mon information personnelle, dans ton code, si une exception se produit, est ce que Result risque de de pas être initialisé ?

    C'est pourquoi j'avais mis Result := ... au début de mon code.

    Peux tu m'éclairer sur ce point ?

    A+
    Charly

  20. #20
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 754
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 754
    Points : 13 340
    Points
    13 340
    Par défaut
    Non, Result ne sera pas initialisé en cas d'exception mais le seul problème qui puisse survenir est que InstallDate ne soit pas un entier (REG_DWORD)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture du registre avec Windows 7 x64
    Par leSeb dans le forum VB.NET
    Réponses: 5
    Dernier message: 28/11/2012, 18h49
  2. Lecture du Registre Windows
    Par mourbare dans le forum Windows
    Réponses: 2
    Dernier message: 27/02/2008, 08h42
  3. [Windows]accès base de registre windows
    Par Greg01 dans le forum API standards et tierces
    Réponses: 27
    Dernier message: 05/06/2007, 15h14
  4. [CR9] Lecture du registre
    Par exyacc dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 04/11/2005, 11h17
  5. Réponses: 4
    Dernier message: 23/07/2003, 13h07

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