suivi des modifications du registre

Programmation d'applications complexes
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

suivi des modifications du registre

Message par hardy »

Après 3 mois d'absence, me revoilà !
Pas eu le temps de programmer : trop de boulot !
Au passage, je vais me remettre à ma contribution promise pour soundeditor.
En attendant, j'ai repris ce WE en faisant un petit programme prenant des clichés du registre, et permettant de voir les modifications entre deux clichés.
Marche sous windows XP au moins.
Dans le code, il n'y a qu'a modifier l'icône, et l'image.
Pour faire un cliché, j'utilise regedit : c'est ce qu'il y a de plus rapide. (5-6 secondes)
Ensuite on convertit le fichier obtenu (c'est de l'unicode), pour avoir un fichier ANSI avec des chaînes finissant par 0.
Globalement, chez moi, un cliché prend 8 secondes.
Ensuite, la procédure d'analyse des modifications détermine les clés effacées / crées / modifiées. (chez moi, analyse en environ 1 seconde : pas mal non?)

A noter : j'ai fait diverses procédures de conversion et d'analyse avant d'arriver à cette forme : pour l'analyse, par exemple, la première prenait environ 600 secondes, puis la deuxième (avec des listes chainées), environ 150 secondes !. En fait, pour optimiser, il faut travailler avec des zones mémoire, et le moins de variables possible.
De même, pour la conversion UNICODE / ANSI, si on ne charge pas le fichier intégralement en mémoire, pour travailler dessus, c'est la catastrophe : très long à cause des multiples accès disque.

Voilà le code (j'apporterai des améliorations, notamment la possibilité d'afficher pour les clés modifiées les valeurs anciennes et nouvelles : plus grand chose à faire)
Pour l'utiliser, créer un exe dans un dossier quelconque.

Dites-moi ce que ça donne chez vous. (pour faire des tests, modifier le registre avec regedit, ou installer / désinstaller des bricoles)

Code : Tout sélectionner

Global path.s,nbimage
path=Space(255) 
GetModuleFileName_(0,@path,255)

While Right(path,1)<>"\"
path=Left(path,Len(path)-1)
Wend

CreateDirectory(path+"clichés")

;path="c:\surveillance\"

; A MODIFIER--------------- ainsi que le la fin (label Berlioz)

LoadImage(0,path+"berlioz.ico")

;----------------déclarations ---------------------

Declare cliche()
Declare suppression()
Declare comparer()
Declare sauver()
Declare refresh()

;--------------- Lecture config---------------------
Dim image.s(200)
Dim temps.s(200)
nbimage=0
If ReadFile(0,path+"breg.cfg")
  Repeat
    nbimage+1
    image(nbimage)=ReadString()
    temps(nbimage)=ReadString()
  Until Eof(0) Or nbimage=199
  CloseFile(0)
EndIf


;--------------Main------------------------
start=1 : run=1 

h=OpenProcess_($1F0FFF,0,GetCurrentProcessId_())
SetPriorityClass_(h,#HIGH_PRIORITY_CLASS)
CloseHandle_(h)

titre.s="Suivi du registre"
win.l=OpenWindow(0,0,0,530,380,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget|#PB_Window_Invisible,titre)

couleur=GetSysColor_(#COLOR_3DFACE)

CreateGadgetList(win)
CreateImage(2,167,60)
StartDrawing(ImageOutput())
Box(0,0,167,60,couleur)
Locate(0,0)
FrontColor($D6,$B5,$29)
DrawingMode(1)
LoadFont(0,"Times New Roman",12,#PB_Font_Italic|#PB_Font_HighQuality)
DrawingFont(FontID())
DrawText("Suivi registre v 1.0")
Locate(0,18)
DrawText("Pascal Tonnelier")
Locate(0,36)
DrawText("12/2004")
CloseFont(0)
StopDrawing()
ImageGadget(99,355,290,167,60,UseImage(2))
Image= CatchImage(1, ?Berlioz)
StartDrawing(ImageOutput())
DrawingMode(4)
FrontColor($D6,$B5,$29)
Box(0,0,167,251)
Box(1,1,165,249)
Box(2,2,163,247)
StopDrawing()
ImageGadget(100, 355,30,167,250,Image)

ListIconGadget(1,0,10,343,330,"Clichés registre",400,#PB_ListIcon_FullRowSelect|#PB_ListIcon_CheckBoxes|#PB_ListIcon_AlwaysShowSelection)
ButtonGadget(2,10,350,100,20,"Prendre un cliché")
ButtonGadget(3,120,350,120,20,"Comparer deux clichés")
ButtonGadget(4,260,350,60,20,"Effacer")

refresh()

run=1
SetWindowText_(win,@titre)
HideWindow(0,1)
AddSysTrayIcon(0,win,UseImage(0))
SysTrayIconToolTip(0,titre)
HideWindow(0,0)
Repeat
event=WaitWindowEvent()

If IsIconic_(win)<>0 And hide=0
HideWindow(0,1):hide=1
EndIf

Select event
    
  Case #PB_Event_SysTray
  HideWindow(0,0):hide=0
  SetForegroundWindow_(win)
  Case #PB_Event_CloseWindow
 ;   If MessageRequester("Suivi de registre","            Quitter?",#PB_MessageRequester_YesNo)=6
  run=0
 ; EndIf 
    
  Case #PB_Event_Gadget
    Select EventGadgetID()
      Case 2
        cliche()
      Case 4
        suppression()
      Case 3
        comparer()
  
  EndSelect
  
EndSelect
Until run=0
End

Procedure cliche()
debutcliche:
nom.s=InputRequester("Cliché de registre","Choisissez un nom (uniquement des lettres et des chiffres)","")
  If nom=""
    MessageRequester("Cliché registre","Nom vide = cliché annulé")
    ProcedureReturn
  EndIf
  For i=1 To nbimage
    If nom=image(i)
      MessageRequester("cliché de registre","Nom déjà utilisé")
      Goto debutcliche
    EndIf
  Next i
  
  time.s=Space(255)
  date.s=Space(255)
  gettimeformat_(0,8,0,0,@time,255)
  getdateformat_(0,1,0,0,@date,255)
  date=date+"  "+time
  DeleteFile("c:\bregistre.reg")

  RunProgram("regedit.exe","/e c:\bregistre.reg","",1)
  If ReadFile(0,"c:\bregistre.reg")
    l=Lof()
    *mem=AllocateMemory(l)
    *memo=*mem
    If *mem
      ReadData(*mem,l)
      CloseFile(0)
      DeleteFile("c:\bregistre.reg")
    Else
      CloseFile(0)
      ProcedureReturn
    EndIf
    
    *mem2=AllocateMemory(l)
    *memo2=*mem2
    If *mem And *mem2
      While *mem<*memo+l
        a.b=PeekB(*mem)
        
        If a>0
          ;        count+1
          If a<>13 And a<>10
            count+1  
            PokeB(*mem2,a)
            *mem2+1
            *mem+1
          Else
            PokeB(*mem2,0)
            *mem2+1
            count+1
            Repeat
              *mem+1
            Until  (PeekB(*mem)<>13 And PeekB(*mem)<>10 And PeekB(*mem)>0) Or *mem=*memo+l-1
          EndIf
        Else
          *mem+1
        EndIf
        
      Wend
      
      PokeS(*mem2,"[berliozo]")
      If OpenFile(1,path+"clichés/"+nom+".breg")
        *mem2-count
        UseFile(1)
        WriteData(*mem2,count+11)
        CloseFile(1)
        sauver()
        MessageRequester("Cliché de registre","Cliché effectué")
        nbimage+1
        image(nbimage)=nom
        temps(nbimage)=date
      EndIf
  EndIf
  EndIf 
  FreeMemory(*memo)
  FreeMemory(*memo2)
  sauver()
  refresh()
EndProcedure

Procedure suppression()
  nbimage2=0
  Dim image2.s(200)
  For i=1 To nbimage
    If GetGadgetItemState(1,i-1)=#PB_ListIcon_Checked Or GetGadgetItemState(1,i-1)=#PB_ListIcon_Checked|#PB_ListIcon_Selected
      DeleteFile(path+"clichés/"+image(i)+".breg")
    Else
      nbimage2+1
      image2(nbimage2)=image(i)
    EndIf
  Next i
  nbimage=nbimage2
  For i=1 To nbimage
    image(i)=image2(i)
  Next i
  refresh()
  sauver()
EndProcedure

Procedure comparer()
  n=0
  For i=1 To nbimage
    If GetGadgetItemState(1,i-1)=#PB_ListIcon_Checked Or GetGadgetItemState(1,i-1)=#PB_ListIcon_Checked|#PB_ListIcon_Selected
      n+1
      If n=1 : aa=i :Else: bb=i:EndIf
    EndIf
  Next i
  If n<>2
    MessageRequester("Comparaison de clichés","Sélectionner exactement deux clichés")
    ProcedureReturn
  EndIf
  
  If OpenWindow(10,0,0,600,400,#PB_Window_ScreenCentered|#PB_Window_SystemMenu,"Résultats de la comparaison")
    CreateGadgetList(WindowID(10))
    ListIconGadget(11,5,5,580,380,"Modifications entre le cliché "+Chr(34)+image(aa)+Chr(34)+" et le cliché "+Chr(34)+image(bb)+Chr(34),1500)
    
  If OpenFile(0,path+"clichés\"+image(aa)+".breg") And OpenFile(1,path+"clichés\"+image(bb)+".breg")
    UseFile(0)
    l=Lof()
    *mem=AllocateMemory(l)
    *memoire1=*mem
    If *mem=0
      CloseFile(0)
      CloseFile(1)
      ProcedureReturn
    EndIf
    
    ReadData(*mem,l)
    CloseFile(0)
    memo=*mem+l
    UseFile(1)
    l2=Lof()
    *mem2=AllocateMemory(l2)
    *memoire2=*mem2
    If *mem2=0
      CloseFile(0)
      CloseFile(1)
      FreeMemory(*mem)
      ProcedureReturn
    EndIf
    ReadData(*mem2,l2)
    CloseFile(1)
    memo2=*mem2+l2
    add1.b=0:addd2.b=0
    While PeekS(*mem)<>"[berliozo]" And PeekS(*mem2)<>"[berliozo]"
      count+1
      Select CompareMemoryString(*mem,*mem2,1)
        Case -1
          a.s=PeekS(*mem)
          AddGadgetItem(11,-1,"clé effacée = "+a)
          Repeat
            *mem+Len(a)+1
            a.s=PeekS(*mem)
          Until Left(a,1)="["
        Case 1
          a.s=PeekS(*mem2)
          AddGadgetItem(11,-1,"clé créée = "+a)
          Repeat
            *mem2+Len(a)+1
            a.s=PeekS(*mem2)
          Until Left(a,1)="["
        Case 0
          debut1=*mem
          debut2=*mem2
          a.s=PeekS(*mem)
          Repeat
            *mem+Len(a)+1
            a.s=PeekS(*mem)
          Until Left(a,1)="["
          a.s=PeekS(*mem2)
          Repeat
            *mem2+Len(a)+1
            a.s=PeekS(*mem2)
          Until Left(a,1)="["
          l1=*mem-debut1:l2=*mem2-debut2
          If l1<>l2
            AddGadgetItem(11,-1,"clé modifiéé = "+PeekS(debut1))
          Else
            If CompareMemory(debut1,debut2,l1)=0
              AddGadgetItem(11,-1,"clé modifiée = "+PeekS(debut1))
            EndIf
          EndIf
          
      EndSelect
    Wend
    FreeMemory(*memoire1)
    FreeMemory(*memoire2)
  EndIf
  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
  CloseWindow(10)
EndIf 
EndProcedure

Procedure sauver()
  DeleteFile(path+"breg.cfg")
  If OpenFile(0,path+"breg.cfg")
    For i=1 To nbimage
;      Debug image(i)
;      Debug temps(i)
      WriteStringN(image(i))
      WriteStringN(temps(i))
    Next i
    CloseFile(0)
  EndIf
EndProcedure

Procedure refresh()
  ClearGadgetItemList(1)
  For i=1 To nbimage
    AddGadgetItem(1,-1,image(i)+" : le "+temps(i))
  Next i
EndProcedure




Berlioz:IncludeBinary "d:\imageberliozo.bmp"