Modify infos of numerous files

Just starting out? Need help? Post your questions and find answers here.
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: Modify infos of numerous files

Post by Denis »

Kcc, i send you a private msg.


I' m working to find a solution, but it will take time.
A+
Denis
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Modify infos of numerous files

Post by Kwai chang caine »

Yes i see just now, and i have just terminate the "short" answer :oops: , thanks a lot 8)
ImageThe happiness is a road...
Not a destination
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: Modify infos of numerous files

Post by Denis »

Kcc,

You want only to change value of Version info without caring language (so, you have to detect languages and choose one to change) or you will add a Version info for example in French (so new language will be added or if exist it will be rewritten?
A+
Denis
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: Modify infos of numerous files

Post by Denis »

Slt KCC,

here it is.

So, 3 codes.
The patcher, the reader, the cleaner.

after reflexion, i think that to modify the VersionInfo is not really a good solution.
It's possible to add a resource to a exe/ddl (PE) file.

The code add a RC_DATA resource with an alphanumeric identifiant instead of a numeric one.
The content is data, so, it's possible to add nureric (double etc.) or string etc.

The example store strings.

The rules :
Adding empty string is not possible
Data must be unicode only.
The langage put to these data is #LANG_FRENCH, #SUBLANG_FRENCH
multiple file selection is possible
The example write the same strings to all selected files (string from datasection)
There are some restrictions on resource updates (https://msdn.microsoft.com/en-us/librar ... s.85).aspx)
Files to edit must not be loaded by another application (patcher/cleaner)

The patcher, the reader, the cleaner:
The patcher write add a RC_DATA resource with an alphanumeric identifiant
The reader read the RC_DATA resource with the same alphanumeric identifiant
The cleaner removes the resource with the same alphanumeric identifiant if exists

The patcher

Code: Select all

;// Patcheur pour la resource #RT_RCDATA de fichiers exe/dll (format PE)
;// Codé par denis pour KCC
;//
;// Le code patche la resource d'un fichier exe/dll (format PE)
;// en ajoutant des données en RC_DATA
;// L'identifiant utilisée est de type alphanumérique
;// Le code ne vérifie pas si les données existent en RC_DATA pour l'identifiant alphanumérique
;// L'identifiant utilisée est de type alphanumérique, #KCC_id = "KwaiChangCaine"
;// La langue utilisée pour les données écrites est #LANG_FRENCH, #SUBLANG_FRENCH
;// la multi-sélection de fichiers est possible
;//
;//  A compiler en Unicode! et utiliser le debugger

;// Patcher for #RT_RCDATA resource of exe/dll files (PE format)
;// Coded by denis for KCC
;//
;// The code patches resource of an exe/dll file (PE file format)
;// by adding data in RC_DATA
;// The identifier used is an alphanumeric one
;// The code does not check if RC_DATA exists for the alphanumeric identifier
;// The identifier used is alphanumeric, #KCC_id = "KwaiChangCaine
;// The language used for written data is #LANG_FRENCH, #SUBLANG_FRENCH
;// multiple file selection is possible
;//
;//  Compile only in Unicode! and use the debugger

EnableExplicit


;- 100    --------  Constantes/Constants
;// valeur retournée en cas d'erreur/returned value in case of failure
#Return_Error = #False
;// valeur retournée en cas de succès/returned value if successful
#Return_No_Error = #True

;// identifiant de la resource en RC_DATA/RC_DATA resource identifier
#KCC_id = "KwaiChangCaine"

;// identifiant système de la resource RC_DATA/RC_DATA resource system identifier
#RT_RCDATA = 10

;-
;- 300    --------  Structure
Structure File
      ;// Nom du fichier/File name
      FileName.s
      ;// résultat de l'opération de patchage:
      ;// #True, le patch est Ok, #False, le patchage n'est pas correct ou absent
      ;// result of patching operation:
      ;// #True, Patch is Ok, #False, patching is not correct or absent
      NoError.i
EndStructure

;-
;- 500    --------  Macros
Macro MAKEINTRESOURCE(Value)
      (Value & $FFFF)
EndMacro

Macro MAKELANGID(primary, sublang)
      (((sublang)<<10) | (primary))
EndMacro
;-

;- -- 2000  --------  Procedures
Procedure.i Add_MemoryDATA_String(StringToAdd.s, *MemoryToreturn, closeBuffer = #False)
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: Add_MemoryDATA_String()
      ;//
      ;// BUT/PURPOSE: Réallouer de la mémoire pour stocker les chaînes existantes et y ajouter la nouvelle chaîne passée en paramètre
      ;//              Reallocate memory To store existing strings And add the new string passed As parameter To it
      ;//
      ;// PARAMETRES/PARAMETERS:
      ;//               StringToAdd.s - la chaîne à ajouter/the string to add
      ;//               *MemoryToreturn - adresse d'une variable en mémoire (variable de type pointeur)
      ;//                                  la variable recevra l'adresse de la mémoire qui contient les données
      ;//                                  en cas d'erreur, la variable recevra la valeur #Null
      ;//                                  address of a variable in memory (pointer type variable)
      ;//                                  the variable will receive the address of the memory that contains the data
      ;//                                  in case of failure, the variable will be set to #Null
      ;//               closeBuffer - variable qui prendra une de ces deux valeurs : #True ou #False
      ;//                             variable that will take one of these two values: #True or #False
      ;//                                #True  : on ajoute la chaîne et les variables statiques sont positionnées aux valeurs correctes
      ;//                                #True  : the string is added and the static variables are set to correct values
      ;//
      ;//                                #False : Il n'y a plus de chaîne à ajouter, les données de la mémoire seront alignées sur 4 octets
      ;//                                #False : There is no more string to add, the memory data will be aligned on 4 bytes
      ;//                                         les variables statiques sont positionnées à #Null
      ;//                                         static variables are set to #Null
      ;//
      ;// RETOURNE/RETURN:  en cas de succès, l'adresse mémoire ou sont stockées les chaînes
      ;//                   if successful, the memory address where the strings are stored
      ;//                   #Return_Error en cas d'erreur/#Return_Error in case of failure
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// mémorise le nombre d'octets nécessaire pour stocker la chaîne en mémoire (format Unicode)
      ;// le caractère #NULL de fin de chaîne n'est pas pris en compte
      ;// memorizes the number of bytes needed to store in memory the string (Unicode format)
      ;// the #NULL character of end string is not taken into account
      Protected SizeOfString
      ;// mémorise le nombre d'octets écrits par la fonction PokeS(), non compris le caractère #NULL de fin de chaîne
      ;// memorizes the number of bytes written by the function PokeS() function, not including the #Null character of end string
      Protected NumberOfBytesWritten
      ;// pointeur temporaire pour réallouer de la mémoire
      ;// temporary pointer to reallocate memory
      Protected *NewMemoryID
      ;// pointeur qui conserve l'adresse de la mémoire à chaque appel de la procedure
      ;// pointer that keeps the memory address each time the procedure is called
      Static *memory
      ;// mémorise la position du pointeur lorsque la chaine est écrite, pointe le caractère après le 0 de fin de chaine
      ;// (offset = offset + NumberOfBytesWritten + 2) - la valeur est mémorisé pour chaque appel de la procedure
      ;// memorizes the pointer position when the string is written, points the character after the 0 of end string
      ;// (offset = offset + NumberOfBytesWritten + 2) - the value is kept for each procedure call
      Static offset
      ;// mémorise la taille courante du buffer utilisée pour réallouer correctement la mémoire
      ;// la valeur est mémorisé pour chaque appel de la procedure
      ;// stores the current size of the buffer used to reallocate the memory correctly
      ;// the value is kept For each Procedure call
      Static BufferSize
      
      
      Select closeBuffer
            Case #True
                  ;// on aligne les données, ensuite plus aucune opération sur le buffer !
                  ;// Data are aligned, so no more operations on the buffer!
                  If BufferSize % 4
                        BufferSize + 2
                  EndIf
                  
                  *NewMemoryID = ReAllocateMemory(*memory, BufferSize)
                  If *NewMemoryID = #Return_Error
                        If *memory
                              FreeMemory(*memory)
                              *memory = #Null
                        EndIf
                        offset = #Null
                        BufferSize = #Null
                        PokeI(*MemoryToreturn, #Null)
                        ProcedureReturn #Return_Error
                  EndIf
                  *memory = #Null
                  BufferSize = #Null
                  offset = #Null
                  PokeI(*MemoryToreturn, *NewMemoryID)
                  ProcedureReturn #Return_No_Error
                  
                  
            Default
                  ;// test le pointeur/check pointer
                  If *MemoryToreturn = #Null
                        BufferSize = #Null
                        offset = #Null
                        If *memory
                              FreeMemory(*memory)
                              *memory = #Null
                        EndIf
                        ProcedureReturn #Return_Error
                  EndIf
                  ;// on ajoute la chaîne/add the string
                  If StringToAdd = ""
                        BufferSize = #Null
                        offset = #Null
                        If *memory
                              FreeMemory(*memory)
                              *memory = #Null
                        EndIf
                        PokeI(*MemoryToreturn, #Null)
                        ProcedureReturn #Return_Error
                  EndIf
                  
                  SizeOfString = StringByteLength(StringToAdd)
                  *NewMemoryID = ReAllocateMemory(*memory, BufferSize + SizeOfString + 2)
                  If *NewMemoryID = #Return_Error
                        If *memory
                              FreeMemory(*memory)
                              *memory = #Null
                        EndIf
                        offset = #Null
                        BufferSize = #Null
                        PokeI(*MemoryToreturn, #Null)
                        ProcedureReturn #Return_Error
                  EndIf
                  BufferSize = MemorySize(*NewMemoryID)
                  *memory = *NewMemoryID
                  
                  ;// copie la chaine dans le tampon/copies the string into the buffer
                  NumberOfBytesWritten = PokeS(*memory + offset, StringToAdd, -1, #PB_Unicode)
                  
                  ;// on contrôle que l'on a bien écrit la bonne taille de chaîne/check that the correct string size has been written
                  Select NumberOfBytesWritten
                        Case SizeOfString
                              ;// c'est Ok/it's Ok
                              offset = offset + NumberOfBytesWritten + 2
                              PokeI(*MemoryToreturn, *memory)
                              ProcedureReturn #Return_No_Error
                              
                        Default
                              FreeMemory(*memory)
                              *memory = #Null
                              BufferSize = #Null
                              offset = #Null
                              PokeI(*MemoryToreturn, #Null)
                              ProcedureReturn #Return_Error
                  EndSelect
      EndSelect
EndProcedure

Procedure.i Create_MemoryDATA(List MyStringsListe.s())
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: Create_MemoryDATA()
      ;//
      ;// BUT/PURPOSE: Créer les données RC_DATA en mémoire/Create RC_DATA data in memory
      ;//
      ;// PARAMETRE/PARAMETER:
      ;//                   MyStringsListe.s() - Liste chainée à remplir avec les chaînes pour écriture du tampon
      ;//                                        linked list to fill up with strings, to write them into the buffer
      ;//
      ;// RETOURNE/RETURN:  en cas de succès, l'adresse mémoire de l'ensemble des données à écrire
      ;//                   if successful, the memory address of all data to be written
      ;//                   #Return_Error en cas d'erreur/#Return_Error in case of failure
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// mémorise les données/stores data
      Protected *memory
      ;// chaine courante lue en datasection/current string read in datasection
      Protected StringRead.s = ""
      
      
      ;// chargement de la liste/load the list
      ClearList(MyStringsListe())
      Restore Texte
      
      Read.s StringRead
      While StringRead <> "End_Of_KCC_Section"
            Select AddElement(MyStringsListe())
                  Case #Null
                        MessageRequester("Erreur/Error","Impossible d'allouer de la mémoire pour la liste chaînée" +
                        Chr(10)+Chr(10)+ "Unable to allocate memory for linked list")
                        End
                        
                  Default
                        Select StringRead
                              Case ""
                                    MessageRequester("Erreur/Error","Impossible d'ajouter une chaîne vide à la liste" +
                                    Chr(10)+ "le programme va se terminer" +
                                    Chr(10)+Chr(10)+ "Unable to add an empty string to the list"+
                                    Chr(10)+ "Program aborted")
                                    End
                                    
                              Default
                                    MyStringsListe() = StringRead
                        EndSelect
                        
            EndSelect
            Read.s StringRead
      Wend
      
      ;// Ajouter au buffer mémoire chaque chaîne de la liste/Add each string from the list to memory buffer
      ForEach MyStringsListe()
            If Add_MemoryDATA_String(MyStringsListe(), @*Memory) = #Return_Error
                  ProcedureReturn #Return_Error
            EndIf
      Next
      
      ;// alignement des données, ensuite on n'écrit plus dans le buffer!
      ;// Data are aligned, so no more operations on the buffer!
      If Add_MemoryDATA_String("", @*Memory, #True) = #Return_Error
            ProcedureReturn #Return_Error
      EndIf
      
      ProcedureReturn *memory
EndProcedure

Procedure Write_RCDATA_Resource(List Files.File(), id.s, *pt_Data_Block, SiezOf_Data_Block)
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: Write_RCDATA_Resource()
      ;//
      ;// BUT/PURPOSE: Ecrire les données RC_DATA/Write RC_DATA datas
      ;//
      ;// PARAMETRES/PARAMETERS:
      ;//                   Files.File() - Liste chaînée des fichiers à patcher/Linked list of files to patch
      ;//                                       Files()\FileName :
      ;//                                            contient le nom complet du fichier/contains the full file name
      ;//                                       Files()\NoError :
      ;//                                            recevra une des valeurs suivantes (résultat de l'opération de patchage):
      ;//                                            will receive one of the following values (result of patching operation):
      ;//                                               #True  : le patch est Ok/Patch is Ok
      ;//                                               #False : le patchage n'est pas correct ou absent/patching operation is not correct
      ;//                   id.s - identifiant de la ressource RC_DATA/RC_DATA resource identifier
      ;//                             ici la constante définie #KCC_id/here the defined constant #KCC_id
      ;//                   *pt_Data_Block - pointeur sur la zone mémoire des données à écrire/pointer to the memory area of datas to write
      ;//                   SiezOf_Data_Block - taille mémoire des données à écrire/memory size of datas to write
      ;//
      ;// RETOURNE/RETURN:  Rien/Nothing
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// handle de l'API  BeginUpdateResource_()/handle from the BeginUpdateResource_() API
      Protected BeginUpdateResource
      ;// attributs du fichier avant de les modifier/file attributes before modifying them
      Protected FileAttributes
      
      
      ;// par sécurité/for safety
      If *pt_Data_Block = #Null Or (SiezOf_Data_Block <= 0) Or ListSize(Files()) = 0
            ProcedureReturn #Return_Error
      EndIf
      
      ForEach Files()
            ;// on lit les attributs du fichier avant modifs/read file attributes before changes
            FileAttributes = GetFileAttributes(Files()\FileName)
            ;// on modifie les attributs du fichier avant de le patcher/modify the file attributes before patching it
            SetFileAttributes(Files()\FileName, #PB_FileSystem_Normal)
            
            ;// Retrouve le handle qui sera utilisé par la fonction UpdateResource/Find the handle that will be used by the UpdateResource function
            BeginUpdateResource = BeginUpdateResource_(Files()\FileName, #False)
            
            Select BeginUpdateResource
                  Case #Null
                        Files()\NoError = #False
                        
                  Default
                        ;// ajoute, supprime ou remplace les resources passées en paramètre
                        Select UpdateResource_(BeginUpdateResource, #RT_RCDATA, @id, MAKEINTRESOURCE(MAKELANGID(#LANG_FRENCH, #SUBLANG_FRENCH)), *pt_Data_Block, SiezOf_Data_Block)
                              Case #Return_Error
                                    EndUpdateResource_(BeginUpdateResource, #True)
                                    Files()\NoError = #False
                                    
                              Default
                                    ;// Valide les modifications de la resource/Validates resource changes
                                    Select EndUpdateResource_(BeginUpdateResource, #False)
                                          Case #Return_Error
                                                EndUpdateResource_(BeginUpdateResource, #True)
                                                Files()\NoError = #False
                                                
                                          Default
                                                Files()\NoError = #True
                                    EndSelect
                        EndSelect
            EndSelect
            
            ;// on repositionne les attributs initiaux du fichier/repositions initial attributes of the file
            If FileAttributes <> -1
                  SetFileAttributes(Files()\FileName, FileAttributes)
            EndIf
      Next
EndProcedure

Procedure SelectFileToProcess(List FilesToRead.File())
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: SelectFileToProcess()
      ;//
      ;// BUT/PURPOSE: Ouvre la fenêtre de sélection des fichiers
      ;//              Ajoute des éléments à la liste chaînée pour y stocker les noms de fichier
      ;//              Opens the file selection window
      ;//              Adds elements to the linked list to store file names
      ;//
      ;// PARAMETRE/PARAMETER:
      ;//                   FilesToRead - liste chaînée qui contiendra la liste des fichiers à traiter
      ;//                                 linked list that will contain the list of files to process
      ;//
      ;// RETOURNE/RETURN:  Rien/Nothing
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// Nom du fichier/File name
      Protected File$ = ""
      
      
      ClearList(FilesToRead.File())
      File$ = OpenFileRequester("Open File", "", "Version (exe,dll)|*.exe;*.dll|all files (*.*)|*.*", 0, #PB_Requester_MultiSelection)
      While File$
            Select AddElement(FilesToRead())
                  Case #Null
                        MessageRequester("Erreur/Error","Impossible d'allouer de la mémoire pour la liste chaînée" +
                        Chr(10)+ "le programme va se terminer" +
                        Chr(10)+Chr(10)+ "Unable to allocate memory for linked list"+
                        Chr(10)+ "Program aborted")
                        End
                        
                  Default
                        FilesToRead()\FileName = File$
            EndSelect
            File$ = NextSelectedFileName()
      Wend
EndProcedure

;-
Procedure programme()
      ;// Nom du fichier/File name
      Protected File$ = ""
      ;// pointeur qui recevra l'adresse du bloc mémoire/pointer that will receive the address of memory area
      Protected *memory
      ;// Liste chainée qui contient les chaines à écrire en resource/Linked list that contains strings to write into resource
      Protected NewList MyStringsListe.s()
      ;// Liste chainée qui contient la liste des fichier à modifier/Linked list that contains the listing of files to modify
      Protected NewList Files.File()
      ;// compteur d'erreur/error counter
      Protected NB_Error
      
      
      ;// creation de la liste des fichiers/creation of the list files
      SelectFileToProcess(Files())
      ;// création de la mémoire contenant les chaînes/creates the memory containing the strings
      ;// création de la mémoire contenant les chaînes/creates the memory containing the strings
      If ListSize(Files())
            *memory = Create_MemoryDATA(MyStringsListe())
            If *memory
                  ;// écrit la ressource/ writes the resource
                  Write_RCDATA_Resource(Files(), #KCC_id, *memory, MemorySize(*memory))
            Else
                  MessageRequester("Erreur/Error","Impossible de créer la zone mémoire" +
                  Chr(10)+Chr(10)+ "Unable to create memory area")
                  Debug "Erreur/Error:"
                  Debug "Impossible de créer la zone mémoire"
                  Debug "Unable to create memory area"
                  
            EndIf
            
            ;// affiche les résultats/displays results
            ForEach Files()
                  Select Files()\NoError
                        Case #False
                              Debug "Fichier/File : " + Files()\FileName + Chr(10) + Space(20)+ "Erreur sur le fichier/File error"
                              NB_Error + 1
                  EndSelect
            Next
            If NB_Error = 0
                  MessageRequester("Info","Tous les fichiers ont été modifiés" + Chr(10)+"All files have been changed", #PB_MessageRequester_Info)
            EndIf
            
            ;// libère la mémoire/frees the memory
            If *memory
                  FreeMemory(*memory)
            EndIf
      Else
            MessageRequester("Erreur/Error","Pas de fichier à traiter" +
            Chr(10)+Chr(10)+ "No file to process")
      EndIf
EndProcedure


DataSection
      Texte:
      Data.s "Zone Kcc!"
      Data.s "Version :"
      Data.s "3.00"
      Data.s "Action :"
      Data.s "Delete"
      Data.s "Date :"
      Data.s "March 2010"
      Data.s "Summer Time :"
      Data.s "06h57 PM"
      Data.s "End_Of_KCC_Section"
EndDataSection


programme()
End
The reader

Code: Select all

;// Lecteur pour la resource #RT_RCDATA de fichiers exe/dll (format PE)
;// Codé par denis pour KCC
;//
;// Le code lit le contenu du patch "KwaiChangCaine" de la resources d'un fichier exe/dll (format PE)
;// Le contenu est copié dans un buffer mémoire pour y être lu
;// L'identifiant utilisée est de type alphanumérique, #KCC_id = "KwaiChangCaine"
;// La langue utilisée pour lire les données est #LANG_FRENCH, #SUBLANG_FRENCH
;// la multi-sélection de fichiers est possible
;//
;//  A compiler en Unicode! et utiliser le debugger

;// Reader for resource #RT_RCDATA of exe/dll files (PE format)
;// Coded by denis for KCC
;//
;// The code reads the content of the "KwaiChangCaine" patch from the resource of an exe/dll files (PE format)
;// Content is copied to a memory buffer to be read
;// The identifier used is an alphanumeric one, #KCC_id = "KwaiChangCaine"
;// The language used for this item is #LANG_FRENCH, #SUBLANG_FRENCH
;// multiple file selection is possible
;//
;//  Compile only in Unicode! and use the debugger

EnableExplicit


;- 100    --------  Constantes
;// Utilisé pour charger un fichier exe/dll (format PE) en lecture seule (accès au fichier restraint)
;// Used to load an exe/dll file (PE format) to read-only operations (restricted file access)
#LOAD_LIBRARY_AS_DATAFILE = 2
#LOAD_LIBRARY_AS_IMAGE_RESOURCE = $00000020

;// valeur retournée en cas d'erreur/returned value in case of failure
#Return_Error = #False
;// valeur retournée en cas de succès/returned value if successful
#Return_No_Error = #True
;// valeur retournée lorsque la resource est absente/returned value when resource is lacking
#Return_No_KCC_Resource = -1
;// valeur retournée lorsque le fichier n'existe pas/returned value when the file does not exist
#Return_File_No_Found = -2
;// valeur retournée lorsque un pointeur est nul/returned value when a pointer is null
#Return_Pointer_Null = -3
;// valeur retournée lorsqu'il est impossible de charger un fichier/returned value when a file can not be loaded
#Return_Unable_to_load_File = -4
;// valeur retournée lorsqu'il est impossible d'allouer de la mémoire/returned value when unable to allocate memory
#Return_Unable_to_Allocate_Memory = -5

;// identifiant de la resource en RC_DATA/RC_DATA resource identifier
#KCC_id = "KwaiChangCaine"

;// identifiant système de la resource RC_DATA/RC_DATA resource system identifier
#RT_RCDATA = 10

;-
;- 300    --------  Structure
Structure File
      ;// Nom du fichier/File name
      FileName.s
      ;// résultat de l'opération de patchage:
      ;// #True, le patch est Ok, #False, le patchage n'est pas correct ou absent
      ;// result of patching operation:
      ;// #True, Patch is Ok, #False, patching is not correct or absent
      NoError.i
EndStructure

;-
;- 500    --------  Macros
Macro MAKEINTRESOURCE(Value)
      (Value & $FFFF)
EndMacro

Macro MAKELANGID(primary, sublang)
      (((sublang)<<10) | (primary))
EndMacro
;-

;- -- 2000  --------  Procedures
Procedure.i LoadDatasFromResource(File.s, *pt_FilesToRead_NoError, id.s, *memoryToreturn)
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: LoadDatasFromResource()
      ;//
      ;// BUT/PURPOSE: Créer une zone mémoire  pour y copier le bloc de données de la resource si elle existe
      ;//              Create a memory area to copy the resource data block if exists
      ;//
      ;// PARAMETRES/PARAMETERS:
      ;//                   File.s - Nom du fichier exe/dll avec chemin/exe/dll file name with path
      ;//                   *pt_FilesToRead_NoError - adresse d'une variable en mémoire (integer) qui recevra le code d'erreur pour le fichier courant
      ;//                                             address of a variable in memory (integer) that will receive the error code for the current file
      ;//                   id.s - identifiant de la ressource RC_DATA/RC_DATA resource identifier
      ;//                             ici la constante définie #KCC_id/here the defined constant #KCC_id
      ;//               *memoryToreturn - adresse d'une variable en mémoire (variable de type pointeur)
      ;//                                  la variable recevra l'adresse de la mémoire qui contient les données
      ;//                                  en cas d'erreur, la variable recevra la valeur #Null
      ;//                                  address of a variable in memory (pointer type variable)
      ;//                                  the variable will receive the address of the memory that contains the data
      ;//                                  in case of failure, the variable will be set to #Null
      ;//
      ;// RETOURNE/RETURN:  en cas de succès, l'adresse mémoire ou sont stockées les chaînes
      ;//                   Le fichier n'est plus utilisé ni chargé après cette opération
      ;//                   #Return_Error en cas d'erreur
      ;//                   if successful, the memory address where the strings are stored
      ;//                   The file is no longer used Or loaded after this operation
      ;//                   #Return_Error in case of failure
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// handle du fichier (PE)/handle of the file (PE)
      Protected hModule
      ;// handle du bloc d'informations de la resource/handle of the resource information block
      Protected Find_Resource
      ;// handle du bloc mémoire d'informations des données de la ressource/handle of the resource data information memory block
      Protected LoadResource_RT_RCDATA
      ;// taille des données de la ressource RT_RCDATA/RT_RCDATA resource data size
      Protected SizeofResource
      ;// pointeur sur le premier octet de la ressource RT_RCDATA/pointer to the first byte of the RT_RCDATA resource
      Protected *LockResource
      ;// pointeur qui mémorise l'adresse du buffer mémoire/pointer that memorizes the memory buffer address
      Protected *memory
      
      
      ;// test le pointeur/check pointer
      If *memoryToreturn = #Null
            PokeI(*pt_FilesToRead_NoError, #Return_Pointer_Null)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// test le fichier/check file
      If File = ""
            PokeI(*pt_FilesToRead_NoError, #Return_File_No_Found)
            PokeI(*memoryToreturn, #Null)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// Charge le module spécifié dans l'espace d'adressage du processus appelant. Le module spécifié peut provoquer le chargement d'autres modules
      ;// Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded
      hModule = LoadLibraryEx_(File, 0, #LOAD_LIBRARY_AS_DATAFILE|#LOAD_LIBRARY_AS_IMAGE_RESOURCE)
      If hModule = #Null
            PokeI(*pt_FilesToRead_NoError, #Return_Unable_to_load_File)
            PokeI(*memoryToreturn, #Null)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// Détermine l'emplacement de la ressource avec le type, le nom et la langue spécifiés dans le module spécifié
      ;// Determines the location of the resource with the specified type, name, and language in the specified module
      Find_Resource = FindResourceEx_(hModule, MAKEINTRESOURCE(#RT_RCDATA), id, MAKELANGID(#LANG_FRENCH, #SUBLANG_FRENCH))
      If Find_Resource = #Return_Error
            PokeI(*pt_FilesToRead_NoError, #Return_No_KCC_Resource)
            PokeI(*memoryToreturn, #Null)
            FreeLibrary_(hModule)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// Récupère un handle qui peut être utilisé pour obtenir un pointeur vers le premier octet de la ressource spécifiée en mémoire
      ;// Retrieves a handle that can be used To obtain a pointer To the first byte of the specified resource in memory
      LoadResource_RT_RCDATA = LoadResource_(hModule, Find_Resource)
      If  LoadResource_RT_RCDATA = #Return_Error
            PokeI(*pt_FilesToRead_NoError, #Return_No_KCC_Resource)
            PokeI(*memoryToreturn, #Null)
            FreeLibrary_(hModule)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// Récupère un pointeur sur la ressource spécifiée en mémoire
      ;// Retrieves a pointer To the specified resource in memory
      *LockResource = LockResource_(LoadResource_RT_RCDATA)
      If *LockResource = #Return_Error
            PokeI(*pt_FilesToRead_NoError, #Return_No_KCC_Resource)
            PokeI(*memoryToreturn, #Null)
            FreeLibrary_(hModule)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// Récupère la taille, en octets, de la ressource spécifiée
      ;// Retrieves the size, in bytes, of the specified resource
      SizeofResource = SizeofResource_(hModule, Find_Resource)
      If SizeofResource = 0
            PokeI(*pt_FilesToRead_NoError, #Return_No_KCC_Resource)
            PokeI(*memoryToreturn, #Null)
            FreeLibrary_(hModule)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// alloue la mémoire pour charger les données de la resource du fichier
      ;// Allocate memory to load data from the file's resource
      *memory = AllocateMemory(SizeofResource)
      If *memory = #Return_Error
            PokeI(*pt_FilesToRead_NoError, #Return_Unable_to_Allocate_Memory)
            PokeI(*memoryToreturn, #Null)
            FreeLibrary_(hModule)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// copie des données en mémoire
      ;// copy data into memory
      CopyMemory(*LockResource, *memory, SizeofResource)
      
      FreeLibrary_(hModule)
      
      PokeI(*pt_FilesToRead_NoError, #True)
      ;// retourne l'adresse mémoire des données via *memoryToreturn
      ;// returns the memory address of the data via * MemoryToreturn
      PokeI(*memoryToreturn, *memory)
      
      ProcedureReturn #Return_No_Error
EndProcedure

Procedure.i ExtractStringFromMemory(List myStringsListe.s(), *pt_FilesToRead_NoError, *pt_memory)
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: ExtractStringFromMemory()
      ;//
      ;// BUT/PURPOSE: Extraire les chaines du buffer et les ajouter à la liste chaînée passée en paramètre
      ;//              Extract the strings from the buffer and add them to the linked list passed as a parameter
      ;//
      ;// PARAMETRES/PARAMETERS:
      ;//                   myStringsListe() - liste chaînée qui contiendra les chaînes retrouvées
      ;//                                      Linked List that will contain the strings found
      ;//                   *pt_memory - adresse d'une variable en mémoire (variable de type pointeur)
      ;//                                la variable doit contenir l'adresse de la mémoire qui contient les données
      ;//                                address of a variable in memory (pointer type variable)
      ;//                                the variable must contain the address of the memory that contains the data
      ;//
      ;// RETOURNE/RETURN:  #Return_No_Error en cas de succès/#Return_No_Error if successful
      ;//                   #Return_Error en cas d'erreur/#Return_Error in case of failure
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// adresse du buffer mémoire/memory buffer address
      Protected *memory
      ;// taille courante de la mémoire/current memory size
      Protected Size
      ;// pointeur temporaire utilisé pour se déplacer dans le buffer et retrouver les chaînes
      ;// temporary pointer used to move through the buffer to find the strings
      Protected *memory_temp
      ;// variable de boucle/loop variable
      Protected quit
      
      ;// test le pointeur/check pointer
      If *pt_memory = #Null
            PokeI(*pt_FilesToRead_NoError, #Return_Pointer_Null)
            ProcedureReturn #Return_Error
      EndIf
      
      *memory = PeekI(*pt_memory)
      If *memory = #Null
            PokeI(*pt_FilesToRead_NoError, #Return_Pointer_Null)
            ProcedureReturn #Return_Error
      EndIf
      
      ;// allocation du pointeur temporaire/temporary pointer allocation
      *memory_temp = *memory
      
      Size = MemorySize(*memory)
      
      ClearList(myStringsListe())
      
      While quit = #False
            Select AddElement(myStringsListe())
                  Case #Null
                        MessageRequester("Erreur/Error","Impossible d'allouer de la mémoire pour la liste chaînée" +
                        Chr(10)+ "le programme va se terminer" +
                        Chr(10)+Chr(10)+ "Unable to allocate memory for linked list" +
                        Chr(10)+ "Program aborted")
                        End
                        
                  Default
                        myStringsListe() = PeekS(*memory_temp, -1, #PB_Unicode)
                        Select  myStringsListe()
                              Case ""
                                    quit = #True
                                    
                              Default
                                    *memory_temp + StringByteLength(myStringsListe()) + 2
                        EndSelect
            EndSelect
      Wend
      
      PokeI(*pt_FilesToRead_NoError, #True)
      ProcedureReturn #Return_No_Error
EndProcedure

Procedure.i ExtractResourceString(*pt_Memory, *pt_error, List FilesToRead.File(), List StringsListeToFillUp.s())
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: ExtractResourceString()
      ;//
      ;// BUT/PURPOSE: Boucle sur l'ensemble des fichiers et retrouve la resource pour chaque fichier
      ;//              C'est dans cette fonction qu'il faut ajouter du code pour faire ce qu'il y a à faire
      ;//              Scan all files and finds the resource for each file
      ;//              It is in this function that you have to add code to do what you have to do
      ;//
      ;// PARAMETRES/PARAMETERS:
      ;//                   *pt_memory - adresse d'une variable en mémoire (variable de type pointeur)
      ;//                                la variable doit contenir l'adresse de la mémoire qui contient les données
      ;//                                address of a variable in memory (pointer type variable)
      ;//                                the variable must contain the address of the memory that contains the data
      ;//                   *pt_error - adresse d'une variable en mémoire (variable de type integer) qui recevra le
      ;//                               nombre d'erreurs arrivé lors de la lecture de la resource
      ;//                               address of a variable in memory (integer variable) that will receive the number
      ;//                               of errors that occurred while reading the resource
      ;//                   FilesToRead() - liste chaînée qui contient la liste des fichiers à traiter
      ;//                                   Linked list that contains the list of files to be processed
      ;//                   StringsListeToFillUp() - liste chaînée qui contiendra les chaînes retrouvées
      ;//                                   Linked list that will contain the strings found
      ;//
      ;// RETOURNE/RETURN:  #Return_No_Error en cas de succès/#Return_No_Error if successful
      ;//                   #Return_Error en cas d'erreur/#Return_Error in case of failure
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// pointeur qui mémorise l'adresse du buffer mémoire/pointer that memorizes the memory buffer address
      Protected *memory
      ;// nombre d'erreurs/number of errors
      Protected NB_Error
      ;// positionné si une erreur intervient lors du chargement du fichier courant
      Protected FilesToRead_NoError
      
      ;// test le pointeur/check pointer
      If *pt_Memory = 0 Or *pt_error = 0
            ProcedureReturn #Return_Error
      EndIf
      
      *memory = PeekI(*pt_Memory)
      
      ForEach FilesToRead()
            If *memory
                  FreeMemory(*memory)
            EndIf
            *memory = 0
            ;// on charge les données de la resource dans la mémoire, pour chaque fichier
            ;// The resource data is loaded into the memory, for each file
            Select LoadDatasFromResource(FilesToRead()\FileName, @FilesToRead_NoError, #KCC_id, @*memory)
                  Case #Return_No_Error
                        FilesToRead()\NoError = FilesToRead_NoError
                        ;// extrait et charge les chaînes dans la liste chainée passée en paramètre
                        ;// Extracts and loads strings in the linked list passed as a parameter
                        Select ExtractStringFromMemory(StringsListeToFillUp(), @FilesToRead_NoError, @*memory)
                              Case #Return_No_Error
                                    FilesToRead()\NoError = FilesToRead_NoError
                                    
                              Default
                                    NB_Error + 1
                                    FilesToRead()\NoError = FilesToRead_NoError
                        EndSelect
                        
                  Default
                        FilesToRead()\NoError = FilesToRead_NoError
            EndSelect
            
            
            
            ;//////////////////////////////////////////////////////////////////////////////////////////
            ;// ici la liste chaînée StringsListeToFillUp() contient les chaînes de la resource
            ;// mettre ici le code pour traiter le résultat
            ;// here the linked list StringsListeToFillUp () contains the resource strings
            ;// Put here the code to process result
            
            Select FilesToRead()\NoError
                        ;// affiche les résultats/displays results
                  Case #Return_No_KCC_Resource
                        ;// valeur retournée lorsque la resource est absente/returned value when resource is lacking
                        NB_Error + 1
                        Debug "Fichier/File : " + FilesToRead()\FileName + Chr(10) + Space(20)+ "la resource est absente 222/resource is lacking"
                        
                  Case #Return_File_No_Found
                        ;// valeur retournée lorsque le fichier n'existe pas/returned value when the file does not exist
                        NB_Error + 1
                        Debug "Fichier/File : " + FilesToRead()\FileName + Chr(10) + Space(20)+ "le fichier n'existe pas/the file does not exist"
                        
                  Case #Return_Pointer_Null
                        ;// valeur retournée lorsque un pointeur est nul/returned value when a pointer is null
                        NB_Error + 1
                        Debug "Fichier/File : " + FilesToRead()\FileName + Chr(10) + Space(20)+ "un pointeur est nul/a pointer is null"
                        
                  Case #Return_Unable_to_load_File
                        ;// valeur retournée lorsqu'il est impossible de charger un fichier/returned value when a file can not be loaded
                        NB_Error + 1
                        Debug "Fichier/File : " + FilesToRead()\FileName + Chr(10) + Space(20)+ "impossible de charger un fichier/file can not be loaded"
                        
                  Case #Return_Unable_to_Allocate_Memory
                        ;// valeur retournée lorsqu'il est impossible d'allouer de la mémoire/returned value when unable to allocate memory
                        NB_Error + 1
                        Debug "Fichier/File : " + FilesToRead()\FileName + Chr(10) + Space(20)+ "impossible d'allouer de la mémoire/unable to allocate memory"
                        
                  Case #True
                        Debug "Fichier/File : " + FilesToRead()\FileName + Chr(10)  + "  lecture/Reading of KCC resource 111  Ok" + Chr(10)
                        Debug "resource :"
                        Debug "----------- :"
                        ForEach StringsListeToFillUp()
                              Debug StringsListeToFillUp()
                        Next
            EndSelect
            Debug ""
            
            ;//////////////////////////////////////////////////////////////////////////////////////////
            
            
            
            
            PokeI(*pt_error, NB_Error)
      Next
      
      
      If NB_Error
            ProcedureReturn #Return_Error
      Else
            ProcedureReturn #Return_No_Error
      EndIf
EndProcedure

Procedure SelectFileToProcess(List FilesToRead.File())
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: SelectFileToProcess()
      ;//
      ;// BUT/PURPOSE: Ouvre la fenêtre de sélection des fichiers
      ;//              Ajoute des éléments à la liste chaînée pour y stocker les noms de fichier
      ;//              Opens the file selection window
      ;//              Adds elements to the linked list to store file names
      ;//
      ;// PARAMETRE/PARAMETER:
      ;//                   FilesToRead - liste chaînée qui contiendra la liste des fichiers à traiter
      ;//                                 linked list that will contain the list of files to process
      ;//
      ;// RETOURNE/RETURN:  Rien/Nothing
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// Nom du fichier/File name
      Protected file$ = ""
      
      
      ClearList(FilesToRead.File())
      file$ = OpenFileRequester("Open File", "", "Version (exe,dll)|*.exe;*.dll|all files (*.*)|*.*", 0, #PB_Requester_MultiSelection)
      While file$
            Select AddElement(FilesToRead())
                  Case #Null
                        MessageRequester("Erreur/Error","Impossible d'allouer de la mémoire pour la liste chaînée" +
                        Chr(10)+Chr(10)+ "Unable to allocate memory for linked list")
                        End
                        
                  Default
                        FilesToRead()\FileName = file$
            EndSelect
            file$ = NextSelectedFileName()
      Wend
EndProcedure

Procedure programme()
      ;// Nom du fichier/Name file
      Protected file$ = ""
      ;// pointeur qui mémorise l'adresse du buffer mémoire/pointer that memorizes the memory buffer address
      Protected *memory
      ;// liste chaînée qui contiendra les chaînes à écrire de la resource
      ;// Linked list that will contain the strings to write from the resource
      Protected NewList myStringsListe.s()
      ;// Liste chainée qui contient la liste des fichiers à modifier
      ;// Linked list that contains the files list to change
      Protected NewList files.File()
      ;// nombre d'erreurs/number of errors
      Protected NB_Error
      
      
      ;// creation de la liste des fichiers/creation of the list files
      SelectFileToProcess(files())
      
      Select ListSize(files())
            Case #Null
                  MessageRequester("Erreur/Error","Pas de fichier à traiter" +
                  Chr(10)+Chr(10)+ "No file to process")
                  
            Default
                  ExtractResourceString(@*memory, @NB_Error, files(), myStringsListe())
                  If NB_Error
                        MessageRequester("Error","Il y a des erreurs" + Chr(10)+"Errors occurred", #PB_MessageRequester_Info)
                  Else
                        MessageRequester("Info","Tous les fichiers ont été correctement lus" + Chr(10)+"All files have been correctly readen", #PB_MessageRequester_Info)
                  EndIf
      EndSelect
      
      ;// libère la mémoire
      If *memory
            FreeMemory(*memory)
      EndIf
EndProcedure


programme()
End
Last edited by Denis on Mon Jun 18, 2018 6:16 pm, edited 1 time in total.
A+
Denis
Denis
Enthusiast
Enthusiast
Posts: 704
Joined: Fri Apr 25, 2003 5:10 pm
Location: Doubs - France

Re: Modify infos of numerous files

Post by Denis »

And the cleaner
The cleaner

Code: Select all

;// Cleaner pour la resource #RT_RCDATA de fichiers exe/dll (format PE)
;// Codé par denis pour KCC
;//
;// Le code supprime la resources #KCC_id = "KwaiChangCaine" d'un fichier exe/dll (format PE) si elle existe
;// L'identifiant utilisée est de type alphanumérique, #KCC_id = "KwaiChangCaine"
;// La langue utilisée pour les données écrites est #LANG_FRENCH, #SUBLANG_FRENCH
;// la multi-sélection de fichiers est possible

;//  A compiler en Unicode! et utiliser le debugger
;//

;// Cleaner for resource #RT_RCDATA of exe/dll files (PE format)
;// Coded by denis for KCC
;// The code removes the #KCC_id = "KwaiChangCaine" resources from an exe / dll file (PE format) if it exists
;// The identifier used is an alphanumeric one, #KCC_id = "KwaiChangCaine"
;// The language used for this item is #LANG_FRENCH, #SUBLANG_FRENCH
;// multiple file selection is possible

;//  Compile only in Unicode! and use the debugger

EnableExplicit


;- 100    --------  Constantes
;// valeur retournée en cas d'erreur/returned value in case of failure
#Return_Error = #False
;// valeur retournée en cas de succès/returned value if successful
#Return_No_Error = #True
;// valeur retournée lorsque la resource est absente/returned value when resource is lacking
#Return_No_KCC_Resource = -1
;// valeur retournée lorsque le fichier n'existe pas/returned value when the file does not exist
#Return_File_No_Found = -2

;// identifiant de la resource en RC_DATA/RC_DATA resource identifier
#KCC_id = "KwaiChangCaine"

;// identifiant système de la resource RC_DATA/RC_DATA resource system identifier
#RT_RCDATA = 10

;-
;- 300    --------  Structure
Structure File
      ;// Nom du fichier/File name
      FileName.s
      ;// résultat de l'opération de patchage:
      ;// #True, le patch est Ok, #False, le patchage n'est pas correct ou absent
      ;// result of patching operation:
      ;// #True, Patch is Ok, #False, patching is not correct or absent
      NoError.i
EndStructure

;-
;- 500    --------  Macros
Macro MAKEINTRESOURCE(Value)
      (Value & $FFFF)
EndMacro

Macro MAKELANGID(primary, sublang)
      (((sublang)<<10) | (primary))
EndMacro
;-

;- -- 2000  --------  Procedures
Procedure.i Delete_KCC_Resource_FromFile(List File.File(), id.s, *pt_error)
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: Write_RCDATA_Resource()
      ;//
      ;// BUT/PURPOSE: Supprimer les Datas en resource nommées "KwaiChangCaine" (RT_RCDATA)
      ;//              Delete the resource data named "KwaiChangCaine" (RT_RCDATA)
      ;//
      ;// PARAMETRES/PARAMETERS:
      ;//                   File.File() - liste chaînée qui contiendra la liste des fichiers à traiter
      ;//                                 linked list that will contain the list of files to process
      ;//                                    File()\FileName contient le nom complet du fichier
      ;//                                    File()\NoError recevra une des valeurs suivantes (résultat de l'opération de d'effacement):
      ;//                                       #True, l'effacement est Ok, #False, l'effacement n'est pas correct ou la resource est absente
      ;//                                    File()\FileName contains the full file name
      ;//                                    File()\NoError will receive one of the following values (result of the delete operation):
      ;//                                         #True, Deleting is Ok
      ;//                                         #False, Deleting did not take place
      ;//                                         #Return_No_KCC_Resource, resource is lacking
      ;//                   id.s - identifiant de la ressource RC_DATA/RC_DATA resource identifier
      ;//                             ici la constante définie #KCC_id/here the defined constant #KCC_id
      ;//                   *pt_error - adresse d'une variable en mémoire (variable de type integer) qui recevra le
      ;//                               nombre de fichiers en erreurs pour l'opération d'effacement de la resource
      ;//                               address of a variable in memory (integer variable) that will receive the number
      ;//                               of files in error for the resource deletion operation
      ;//
      ;// RETOURNE/RETURN:  Retourne #Return_No_Error en cas de succès
      ;//                   Retourne #Return_Error en cas d'erreur
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// handle de l'API  BeginUpdateResource_()/handle from the BeginUpdateResource_() API
      Protected BeginUpdateResource
      ;// handle du bloc d'informations de la resource/handle of the resource information block
      Protected Find_Resource
      ;// handle du bloc mémoire d'informations des données de la ressource/handle of the resource data information memory block
      Protected LoadResource_RT_RCDATA
      ;// pointeur sur le premier octet de la ressource RT_RCDATA/pointer to the first byte of the RT_RCDATA resource
      Protected *LockResource
      ;// attributs du fichier avant de les modifier/file attributes before modifying them
      Protected FileAttributes
      ;// compteur d'erreur/error counter
      Protected NB_Error
      
      ;// test le pointeur/check pointer
      If *pt_error = 0
            ProcedureReturn #Return_Error
      EndIf
      
      If ListSize(File()) = 0
            ProcedureReturn #Return_Error
      EndIf
      
      ForEach File()
            Select  FileSize(File()\FileName)
                  Case -1, -2
                        NB_Error + 1
                        File()\NoError = #Return_File_No_Found
                        
                  Default
                        ;// mémorise les attributs du fichier/stores the file attributes
                        FileAttributes = GetFileAttributes(File()\FileName)
                        ;// on modifie les attributs du fichier afin de le modifier/modifies the file attributes to change it
                        SetFileAttributes(File()\FileName, #PB_FileSystem_Normal)
                        
                        ;// Retrouve le handle qui sera utilisé par la fonction UpdateResource/Find the handle that will be used by the UpdateResource function
                        BeginUpdateResource = BeginUpdateResource_(File()\FileName, #False)
                        
                        Select BeginUpdateResource
                              Case #Null
                                    NB_Error + 1
                                    
                              Default
                                    ;// supprime la resource identifiée par id/delete the resource identified by id
                                    Select UpdateResource_(BeginUpdateResource, #RT_RCDATA, @id, MAKEINTRESOURCE(MAKELANGID(#LANG_FRENCH, #SUBLANG_FRENCH)), #Null, 0)
                                          Case #Return_Error
                                                Select GetLastError_()
                                                      Case #ERROR_INVALID_PARAMETER
                                                            File()\NoError = #Return_No_KCC_Resource
                                                EndSelect
                                                
                                                EndUpdateResource_(BeginUpdateResource, #True)
                                                NB_Error + 1
                                                
                                          Default
                                                ;// ;// valide les modifications de la resource/validates resource changes
                                                Select EndUpdateResource_(BeginUpdateResource, #False)
                                                      Case #Return_Error
                                                            EndUpdateResource_(BeginUpdateResource, #True)
                                                            NB_Error + 1
                                                            
                                                      Default
                                                            File()\NoError = #True
                                                EndSelect
                                    EndSelect
                        EndSelect
                        ;// on repositionne les attributs initiaux du fichier/repositions initial attributes of the file
                        If FileAttributes <> -1
                              SetFileAttributes(File()\FileName, FileAttributes)
                        EndIf
            EndSelect
      Next
      
      ;// retourne le nombre d'erreur dans la variable/returns the error number in the variable
      PokeI(*pt_error, NB_Error)
      If NB_Error
            ProcedureReturn #Return_Error
      Else
            ProcedureReturn #Return_No_Error
      EndIf
EndProcedure

Procedure SelectFileToProcess(List FilesToRead.File())
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// FONCTION/FUNCTION: SelectFileToProcess()
      ;//
      ;// BUT/PURPOSE: Ouvre la fenêtre de sélection des fichiers
      ;//              Ajoute des éléments à la liste chaînée pour y stocker les noms de fichier
      ;//              Opens the file selection window
      ;//              Adds elements to the linked list to store file names
      ;//
      ;// PARAMETRE/PARAMETER:
      ;//                   FilesToRead - liste chaînée qui contiendra la liste des fichiers à traiter
      ;//                                 linked list that will contain the list of files to process
      ;//
      ;// RETOURNE/RETURN:  Rien/Nothing
      ;///////////////////////////////////////////////////////////////////////////////////////////////////
      ;// Nom du fichier/File name
      Protected File$ = ""
      
      
      ClearList(FilesToRead.File())
      File$ = OpenFileRequester("Open File", "", "Version (exe,dll)|*.exe;*.dll|all files (*.*)|*.*", 0, #PB_Requester_MultiSelection)
      While File$
            Select AddElement(FilesToRead())
                  Case #Null
                        MessageRequester("Erreur/Error","Impossible d'allouer de la mémoire pour la liste chaînée" +
                        Chr(10)+ "le programme va se terminer" +
                        Chr(10)+Chr(10)+ "Unable to allocate memory for linked list"+
                        Chr(10)+ "Program aborted")
                        End
                        
                  Default
                        FilesToRead()\FileName = File$
            EndSelect
            File$ = NextSelectedFileName()
      Wend
EndProcedure

;-
Procedure programme()
      ;// Nom du fichier
      Protected File$ = ""
      ;// Liste chainée qui contient la liste des fichier à modifier
      Protected NewList Files.File()
      ;// compteur d'erreur
      Protected NB_Error
      
      
      ;// creation de la liste des fichiers/creation of the list files
      SelectFileToProcess(Files())
      Select ListSize(Files())
            Case 0
                  MessageRequester("Erreur/Error","Pas de fichier à traiter" +
                  Chr(10)+Chr(10)+ "No file to process")
                  
            Default
                  Select Delete_KCC_Resource_FromFile(Files(), #KCC_id, @NB_Error)
                        Case #Return_Error
                              Select NB_Error
                                    Case 0
                                          MessageRequester("Error","La valeur du pointeur de la fonction Delete_KCC_Resource_FromFile est nulle"+
                                          Chr(10) + "ou la liste des fichiers est vide" +
                                          Chr(10)+Chr(10)+"The pointer value of function Delete_KCC_Resource_FromFile is nul"+
                                          Chr(10) + "or the file list is empty" , #PB_MessageRequester_Info)
                                          
                                    Default
                                          ForEach Files()
                                                Select Files()\NoError
                                                      Case #Return_File_No_Found
                                                            Debug Files()\FileName
                                                            Debug "Fichier non trouvé absente/File no found"
                                                            Debug ""
                                                            
                                                      Case #Return_No_KCC_Resource
                                                            Debug Files()\FileName
                                                            Debug "Resouce absente/resource lacking"
                                                            Debug ""
                                                            
                                                      Case #False
                                                            Debug Files()\FileName
                                                            Debug "impossible de modifier la resource/unable to change the resource"
                                                            Debug ""
                                                EndSelect
                                          Next
                                          
                                          MessageRequester("Error","Il y a des erreurs" + Chr(10)+"Errors occurred", #PB_MessageRequester_Info)
                              EndSelect
                              
                        Default
                              MessageRequester("Info","Tous les fichiers ont été correctement traités" + Chr(10)+"All files have been properly processed", #PB_MessageRequester_Info)
                  EndSelect
      EndSelect
EndProcedure


programme()
End
A+
Denis
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Modify infos of numerous files

Post by Kwai chang caine »

Waouuuuhh !!!! :shock:
So much work just for me 8)

I have tested your code it works perfectly
I don't know it's possible to adding another ressource, more than the VersionInfo
Your code is really a jewel, and now, thanks to you, i can entre all a "telephone directory" in one EXE 8) :D

It's a little bit different than my first research, for modify the existing "VersionInfos" but it's a more solution for do what i need 8)
Later i put my bad code, who patch the "VersionInfo" :oops:

One thousand of love DENIS for this great job 8)
ImageThe happiness is a road...
Not a destination
Post Reply