Bonjour,
je suis en train de travailler sur un outil interne de mise à jour de MSI...ça fonctionne plutôt bien via l'API MSI depuis Delphi 2005...mais j'ai un petit problème.
Le principe général est le suivant
1) extraction de la ressource MSI du bootstrapper
2) extraction d'un .CAB dans le MSI
3) extraction des fichiers du .CAB
4) compression des fichiers dans un nouveau .CAB
5) remplacer le .CAB dans le MSI
6) remplacer la resource du bootstrapper
j'ai fait les 5 premiers points, mais je constate que le MSI ne change pas de taille alors que je gagne dans les 10Mb sur le .CAB (compression LZX:21 au lieu de MSZip).
pour mettre à jour le MSI j'utilise ceci :
si je réextrait le Stream il est à la bonne taille, j'imagine donc que cela fonctionne...mais le MSI ne change pas de taille
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 TMSIDataBase.UpdateStream(const AStream, AFileName: string); var cQuery : string; cView : THandle; cRecord : THandle; cSize : Cardinal; cCount : Cardinal; cRead : Cardinal; cData : string; begin cQuery := 'UPDATE `_Streams` SET `Data`=? WHERE `Name`=''' + AStream + ''''; Error := MsiDatabaseOpenView(FHandle, PChar(cQuery), cView); try // Create a parameter cRecord := MsiCreateRecord(1); try // Load the file into the record Error := MsiRecordSetStream(cRecord, 1, PChar(AFileName)); // Execute SQL Error := MsiViewExecute(cView, cRecord); finally Error := MsiCloseHandle(cRecord); end; finally MsiViewClose(cView); MsiCloseHandle(cView); end; end;
pire, si je supprime le Stream également :
Comment puis-je récupérer l'espace perdu sans avoir a reconstruire tout le MSI (car j'imagine que c'est une façon de faire...) ?
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 procedure TMSIDatabase.RemoveStream(const AStream: string); var cQuery : string; cView : THandle; begin cQuery := 'DELETE FROM `_Streams` WHERE `Name`=''' + AStream + ''''; Error := MsiDatabaseOpenView(FHandle, PChar(cQuery), cView); try Error := MsiViewExecute(cView, 0); finally Error := MsiViewClose(cView); Error := MsiCloseHandle(cView); end; end;
Merci
Partager