Page 1 sur 2
[R] Recherche dans la base de registre
Posté : mer. 12 janv. 2011 16:44
par ricky
Hello,
je suis en train de faire un programme qui doit contrôler si un programme est installé ou pas sur la machine.
Pour cela je dois aller dans l'arborescence sous :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
Je problème est que je ne sais pas ou ce trouve la clé, donc sous la clé :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
XYZ
Je vais chercher la clé : "DisplayName"="Programme_recherché".
Dans la doc, je n'ai rien trouvé. Sur le forum anglais j'ai trouvé quelque chose (
ici), mais rien pour la recherche. Donc pour l'instant j'ai trouvé une idée détournée (en utilisant ce que j'ai trouvé sur le forum anglais) mais qui me plaît que moyen et marche pas toujours.
Explication idée trouvée : Export dans un fichier de tout ce qu'il y a sous Uninstall. Dans le fichier je vais rechercher la ligne désirée, puis ensuite je recherche le chemin dans lequel elle est et ensuite je ressort l'adresse. Et voilà mon usine à gaz... Quelqu'un pourrait m'aider pour une idée meilleure?
Source ci-dessous...
► Afficher le texte
Code : Tout sélectionner
#include-once
#include "RegFunc.au3"
#Include <File.au3>
$s_key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
$fValue = '"Inno Setup: Icon Group"="PDF-XChange PDF Viewer"'
$valueEnd = _RegSearch ($s_key, $fValue)
MsgBox(0,"test", @TempDir & " : " & $valueEnd)
Func _RegSearch ($s_key , $fValue)
Local $d_file = @TempDir & "\export.txt"
Local $value = _RegExport($d_file, $s_key)
Local $result, $Path, $linePath
; comptage des lignes
Local $linesFile = _FileCountLines($d_file)
Local $file = FileOpen($d_file, 0)
; Check if file opened for reading OK
If $file = -1 Then
MsgBox(0, "Error", "Unable to open file.")
Exit
EndIf
; cherche ligne par ligne
For $i = 1 to $linesFile Step 1
$line = FileReadLine($file, $i)
; prend le 1er caractère de la ligne pour contrôler si c'est le chemin
$result = StringLeft($line, 1)
if $result = "[" then
; Sauvegarde la ligne du chemin
$linePath = $line
; si c'est la ligne qu'on cherche, on sort de la boucle
ElseIf $line = $fValue Then
ExitLoop
ElseIf $i = $linesFile Then
; si la fonction n'a rien trouvé elle retourne 0
$Path = 0
EndIf
Next
FileClose($file)
FileDelete($d_file)
; Enlève les paranthèses carrées
if $Path <> 0 Then
$len = StringLen($linePath) - 2
$Path = StringMid($linePath, 2, $len)
Endif
Return $Path
EndFunc
Merci d'avance
Re: [..]recherche dans la base de registre
Posté : mer. 12 janv. 2011 16:51
par TommyDDR
Je vous conseille d'utiliser les fonctions :
- RegEnumKey()
- RegEnumVal()
- RegRead()
Elles sont assez simple d'utilisatioin et permettent de faire ce que vous souhaitez.
Re: [..]recherche dans la base de registre
Posté : mer. 12 janv. 2011 18:32
par FernandG
Bonsoir,
TommyDDR vous a donné un début de solution, je vous apporte un exemple de code.
Bonne soirée.
AutoItement.
Code : Tout sélectionner
Dim $key, $OSarch
If @OSArch = "X64" Then $OSarch = "64"
$appli = "WinRAR"
$search = "HKEY_LOCAL_MACHINE" & $OSarch & "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
For $i = 1 to 999
$test_key = RegEnumKey($search, $i)
If @error <> 0 then ExitLoop
If StringInStr(RegRead($search & "\" & $test_key, "DisplayName"), $appli) Then
$key = $search & "\" & $test_key
ExitLoop
EndIf
Next
If $key <> "" Then
MsgBox(64, "Information", 'Le logiciel "' & RegRead($key, "DisplayName") & '" est présent sous la clé de la base de registre :' & @CRLF & $key)
Else
MsgBox(16, "Information", 'Le logiciel "' & $appli & """ n'est pas présent dans la base de registre.")
EndIf
Exit
Re: [..] Recherche dans la base de registre
Posté : jeu. 13 janv. 2011 09:26
par zeshrek
Il faut savoir que dans la clé
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{xxxx}
{xxxx} représente le ProductCode de l'application, qui est TOUJOURS le même pour chaque application.
Donc si tu recherches une application bien particulière, il te suffit de te procurer ce ProductCode. Pour cela, plusieurs possibilités.
1/ Tu l'installes sur une machine et tu vas a la recherche de ce dode pour le mettre dans ton autoit
2/ Si ton source d'installation editeur est un MSI, tu utilises par exemple
ORCA pour l'ouvrir, ensuite dans la colonne de gauche tu recherches
Property tu cliques dessus, et dans le tableau de droite tu recherches
ProductCode.
3/ Ton source editeur est un exe (setup.exe, install.exe....) dans ce cas, premiere chose, tu regardes les fichiers livrés avec. Dans le lot il y a peut etre un MSI, dans ce cas, cf 2. Sinon, il faut éssayer de le décompacter, car il peut malgré tout embarquer un MSI. Pour cela je te conseille
Universal Extractor. Il fonctionne comme winzip, winrar... etc. Tu regardes dans ce qu'il t'a trouvé, si il y a un MSI. Si oui, alors cf etape 2, sinon... cf etape 1
Par contre si tu cherches a faire un outil qui par exemple liste les applis installées pour par exemple les désinstaller, là il faut que tu voies du coté de ce que t'ont donnés TommyDDR et FernandG
Re: [..] Recherche dans la base de registre
Posté : jeu. 13 janv. 2011 10:22
par ricky
Merci pour votre aide, voici ce que j'ai fait :
► Afficher le texte
Code : Tout sélectionner
$s_key = clé de base
$fReg = clé a rechercher
$fValue = valeur a comparer
Func _RegSearch ($s_key , $fReg, $fValue)
Local $i=1
Do
$var = RegEnumKey($s_key, $i)
$path = $s_key & "\" & $var
$varRead = RegRead($path , $fReg)
if $varRead = $fValue Then
Return $path
Endif
$i = $i + 1
Until $var = ""
Return "0"
EndFunc
Zeshrek : merci pour ton intervention, je connaissait pas orca, je vais regarder. C'est bien pour un programme msi, je problème, c'est que je ne sais pas quelle version de l'application est installé et je ne peux pas avoir une liste de 100 versions du soft, alors pour être plus souple, c'est la solution la plus simple.
Merci pour votre aide à tous. Problème résolu
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 12:16
par ricky
Zeshrek : Tu m'as l'air d'être un pro en msi. Dans le base de registre je recupére ceci :
UninstallString = MsiExec.exe /I{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}
Comment faire pour désinstaller le programme? J'ai regardé avec le help du msi, mais c'est pas très clair. Voici ce que j'ai essayé :
Code : Tout sélectionner
ShellExecuteWait(MsiExec.exe, "/I{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}", "", "open")
ShellExecuteWait(MsiExec.exe, "/I{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB} /uninstall /norestart", "", "open")
ShellExecuteWait(MsiExec.exe, "/uninstall /norestart |{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}", "", "open")
ShellExecuteWait(MsiExec.exe, "/uninstall /norestart /I{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}", "", "open")
Et ça ne marche pas, ça m'ouvre l'aide
Merci d'avance pour ton aide ou si quelqu'un d'autre connaît la solution, bien sur...
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 12:37
par FernandG
Bonjour,
La commande pour désinstaller un package MSI en connaissant sont "ProductCode" est :
msiexec /qn /norestart /x {ProductCode}
donc dans votre cas, cet exemple devrait convenir

:
Code : Tout sélectionner
RunWait("MsiExec.exe /qn /norestart /x {59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}")
Bonne journée.
AutoItement.
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 12:54
par zeshrek
ricky a écrit :Zeshrek : Tu m'as l'air d'être un pro en msi.
un pro, c'est exactement le mot qui convient vu que depuis 10 ans faire des msi c'est effectivement mon boulot
ricky a écrit :Dans le base de registre je recupére ceci :
UninstallString = MsiExec.exe /I{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}
Comment faire pour désinstaller le programme? J'ai regardé avec le help du msi, mais c'est pas très clair.
En fait plutot que de te faire suer a extraire le productcode de la ligne, tu vas l'exploiter :
Code : Tout sélectionner
$var=regread("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\[color=#FF0000]{xxxx}[/color]","UninstallString ")
Stringreplace($var,"/i","/x")
$var = $var & " /REBOOT=ReallySuppress /qb-" ; attention a bien écrire REBOOT=ReallySuppress exactemetn comme cela, msiexec est sensible a la casse
runwait($var)
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 13:04
par ricky
Parfait, merci, je reste dans ma lignée et je mets ceci :
Code : Tout sélectionner
ShellExecuteWait($result, "/qn /norestart /x " & $param, "", "open")
Zeshrek : je préfére faire comme ci-dessus, car je dois gérer du msi et du exe, donc comme je fais un test, c'est plus facile de l'extraire.
Puisque tu es un pro, j'ai un programme qui est compilé en msi (je n'ai pas les sources), est-il possible d'éditer le msi (je le fais déjà pour modifier certaines choses avec
insted-it) et de lui dire d'aller écrire le chemin de l'install dans le registre? Oumpar le biai de ce numéro unique... Bien entendu, ce chemin n'existe pas dans l'uninstall ni nulle part.
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 14:08
par zeshrek
Bien sur qu'il est possible d'éditer un MSI pour y ajouter/enlever/modifier des choses (sinon je serais au chomedu !).
Pour cela il te faut un logiciel d'édition de MSI. Il y a ORCA donc je t'ai parlé un peu plus tot, mais avec lui ca va etre un peu galère. Sinon il y a les outils d'édition 'pro' comme Wise ou Installshield, mais là, faut du budget. Restent les outils free/shareware (cherche msi free editor sur ton moteur de recherche préféré).
Quel que soit l'outil utilisé le principe reste le même.
1/ tu ouvres ton msi
2/ tu fais tes modifs
3/ tu sauvegardes le transforms (mst) correspondant a ta modif
4/ pour installer ta version modifiée tu lances : msiexec /i Le_nom_du_msi TRANSFORMS=Le_nom_du_mst
Pourquoi je te dis de créer un transforms et non de modifier directement le msi ?
Parceque !
Une des regles de base c'est qu'on ne modifie pas un msi éditeur ! si on veut y apporter des modifications, on fait un mst.
Comme ca si on veut refaire d'autres modifs, soit on modifie le mst, soit on en crée un autre.
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 15:02
par ricky
Je le trouve pas msi editor, mais je cherche encore...
Le problème est que c'est un setup.exe qui lance le msi, donc je suis obligé de modifier le msi.
Mais j'ai insted-it qui peut aussi modifier, mais comment rajouter qu'il écrive le chemin d'install dans le registre?
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 16:07
par zeshrek
msi editor n'est pas un nom de programme mais une famille de programmes. De même que si tu cherchais un logiciel pour modifier du texte, je t'aurai dit de rechercher word processor. Ceci dit, j'ai vu que insted it que tu as peut faire l'affaire, donc pas besoin d'auter chose...
Pour faire en sorte qu'il te mette le chemin dans une clé de registre, il faut que tu ailles sur l'onglet registry, et que tu lui fasses créer par ex dans
HKLM\Softwares\Nom_de_ta_Société\[ProductName]
une valeur, par exemple
InstallPath
avec comme valeur
[INSTALLDIR]
Attention, il faut que ProductName et INSTALLDIR soient tapés ainsi (ce sont des noms de variables internes au msi, et les majuscules/minuscules ont leur importance. De même il faut les mettre entre crochet pour indiquer que ce sont des variables, et donc que c'est leur contenu qui doit etre stocké et non leur nom
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 16:12
par ricky
Je vais essayer ça lundi.
Sinon, est-il possible de recompiler un msi avec un mst dedans? ou patcher le msi? C'est pour éviter de faire les mêmes manips à chaque fois.
Et d'après le numéro dans le registre et le msi, est-il possible de savoir ou il est installé? Mais sans faire une recherche avec le logiciel.exe, c'est trop facile...
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 17:02
par zeshrek
Justement, faire un mst, c'est pour ne pas toucher au msi d'origine. Il est effectivement possible de recompiler le msi en integrant tes modifs dedans, mais c'est contraire aux 'best practices' de MS sur le standard MSI.
Par contre je ne comprend pas ta phrase :
ricky a écrit :Et d'après le numéro dans le registre et le msi, est-il possible de savoir ou il est installé?
De quel numero parles tu ?
En tout cas, si tu fais créer une clé de registre a ton MSI pour qu'il indique l'enddroit ou il s'installe, apres il te suffit de lire cette clé.
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 22:13
par ricky
Oui, mais le "best practices" je suis obligé de les oublier. Car les développeurs qui font le programme n'ont pas la lumière à tout les étages et en plus ils sont commandés par des allemands à la tête dure.
Oui, pour les nouveaux programmes je n'ai qu'à lire la clé de registre.
Mais pour ceux qui sont déjà installés, est-il possible de connaître ou ils sont installés? Comment le MsiExec sait ou le programme est installé?
Ce numéro : MsiExec.exe /I{59BDB81E-9BB8-476E-A0A4-EE053A7FCBCB}
Re: [R] Recherche dans la base de registre
Posté : ven. 14 janv. 2011 23:12
par zeshrek
Peu importe qui a fait le msi, c'est pas une raison pour s'asseoir sur les best practices.
Enfin bon, bref, c'est toi qui vois...
Sinon pour ta question, quand tu as le N° ProductCode tu peux aller rechercher dans
HKLM\SOFTWARE\Microsoft\Windows\currentversion\installer\userdata\S-1-5-18\Products\[ProductCode]\InstallProperties
la valeur LocalPackage
Dans cette valeur tu auras le chemin vers la copie simplifiée du MSI qui est conservée par le système dans c:\windows\installer
Et donc tu peux ensuite aller l'examiner. Avec autoit tu peux par exemple faire un petit script qui ouvre le msi en question avec orca, va dans la table properties, et recherche la property (variable si tu preferes) INSTALLDIR, et résupere son contenu.
Re: [R] Recherche dans la base de registre
Posté : dim. 16 janv. 2011 23:35
par ricky
ricky a écrit :Sinon, est-il possible de recompiler un msi avec un mst dedans? ou patcher le msi? C'est pour éviter de faire les mêmes manips à chaque fois.
Oui, mais on s'est pas compris. Est-il possible de compiler un nouveau msi avec le mst inclus?
zeshrek a écrit :Pour faire en sorte qu'il te mette le chemin dans une clé de registre, il faut que tu ailles sur l'onglet registry, et que tu lui fasses créer par ex dans
HKLM\Softwares\Nom_de_ta_Société\[ProductName]
une valeur, par exemple
InstallPath
avec comme valeur
[INSTALLDIR]
Et mettre ça dans la clé de registre de l'uninstall, est-ce possible?
Re: [R] Recherche dans la base de registre
Posté : lun. 17 janv. 2011 00:16
par zeshrek
ricky a écrit :ricky a écrit :Sinon, est-il possible de recompiler un msi avec un mst dedans? ou patcher le msi? C'est pour éviter de faire les mêmes manips à chaque fois.
Oui, mais on s'est pas compris. Est-il possible de compiler un nouveau msi avec le mst inclus?
Si si on s'est bien compris. Tu peux effectivement enregistrer tes modifications dans le MSI pour en faire un nouveau MSI.
ricky a écrit :zeshrek a écrit :Pour faire en sorte qu'il te mette le chemin dans une clé de registre, il faut que tu ailles sur l'onglet registry, et que tu lui fasses créer par ex dans
HKLM\Softwares\Nom_de_ta_Société\[ProductName]
une valeur, par exemple
InstallPath
avec comme valeur
[INSTALLDIR]
Et mettre ça dans la clé de registre de l'uninstall, est-ce possible?
En théorie oui, mais il ne faut pas. la clé uninstall sert au service de désinstallation.
Par contre rien ne t'empeche de mettre ta clé avec le chemin d'installation ailleurs, et de créer toi même ta propre clé ou tu mettras le chemin d'install de toutes tes applis.
Re: [R] Recherche dans la base de registre
Posté : lun. 17 janv. 2011 08:45
par ricky
Ok, mais comment dire à l'uninstall de supprimer cette clé?
Re: [R] Recherche dans la base de registre
Posté : lun. 17 janv. 2011 09:03
par zeshrek
C'est ca le plus beau, tu n'as pas a lui dire !
Lors de la désinstallation, la clé, vu qu'elle a été posée parle msi, srea supprimée comme le reste du dit msi.
Pour une fois que MS a fait un truc pratique, facile a installer, et qui fonctionne parfaitement, autant ne pas se gener !