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 :
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;
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

pire, si je supprime le Stream également :
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;
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...) ?

Merci