Explorar o código

Pretty sure combining extractarchive with a solid archive may be slow, at least for .7z. Add doc notes and a log warning about this.

Martijn Laan hai 3 meses
pai
achega
c37970bfc5

+ 1 - 0
ISHelp/isetup.xml

@@ -1708,6 +1708,7 @@ Instructs Setup to proceed to comparing time stamps (last write/modified time) i
 </flag>
 <flag name="extractarchive">
 <p>...</p>
+<p>Using a solid archive is not recommended; extraction performance may degrade depending on the solid block size.</p>
 <p>This flag must be combined with <tt>external</tt>.</p>
 <p>This flag is usually combined with the <tt>recursesubdirs</tt> and <tt>createallsubdirs</tt> flags.</p>
 </flag>

+ 2 - 0
Projects/Src/Compression.SevenZipDLLDecoder.Interfaces.pas

@@ -88,6 +88,7 @@ const
   kpidAttrib = 9;
   kpidCTime = 10;
   kpidMTime = 12;
+  kpidSolid = 13;
 
   { From IArchive.h}
   kExtract = 0;
@@ -144,6 +145,7 @@ type
     function GetProperty(index: UInt32; propID: PROPID; out value: OleVariant): HRESULT; stdcall;
     function Extract(indices: Pointer; numItems: UInt32; testMode: Integer;
       extractCallback: IArchiveExtractCallback): HRESULT; stdcall;
+    function GetArchiveProperty(propID: PROPID; out value: OleVariant): HRESULT; stdcall;
   end;
 
   { From IPassword.h }

+ 16 - 5
Projects/Src/Compression.SevenZipDLLDecoder.pas

@@ -32,7 +32,8 @@ type
   TArchiveFindHandle = type Cardinal;
   TOnExtractToHandleProgress = procedure(Bytes: Cardinal);
 function ArchiveFindFirstFileRedir(const DisableFsRedir: Boolean;
-  const ArchiveFilename, DestDir, Password: String; const RecurseSubDirs: Boolean;
+  const ArchiveFilename, DestDir, Password: String;
+  const RecurseSubDirs, ExtractIntent: Boolean;
   out FindFileData: TWin32FindData): TArchiveFindHandle;
 function ArchiveFindNextFile(const FindFile: TArchiveFindHandle; out FindFileData: TWin32FindData): Boolean;
 function ArchiveFindClose(const FindFile: TArchiveFindHandle): Boolean;
@@ -224,9 +225,14 @@ type
 function GetProperty(const InArchive: IInArchive; const index: UInt32;
   const propID: PROPID; const allowedTypes: TVarTypeSet; out value: OleVariant): Boolean; overload;
 { Raises an EOleSysError exception on error but otherwise always sets value,
-  returning True if it's not empty }
+  returning True if it's not empty. Set index to $FFFF to query an archive property
+  instead of an item propery }
 begin
-  var Res := InArchive.GetProperty(index, propID, value);
+  var Res: HRESULT;
+  if index = $FFFF then
+    Res := InArchive.GetArchiveProperty(propID, value)
+  else
+    Res := InArchive.GetProperty(index, propID, value);
   if Res <> S_OK then
     OleError(Res);
   Result := not VarIsEmpty(Value);
@@ -1029,8 +1035,8 @@ begin
 end;
 
 function ArchiveFindFirstFileRedir(const DisableFsRedir: Boolean;
-  const ArchiveFilename, DestDir, Password: String; const RecurseSubDirs: Boolean;
-  out FindFileData: TWin32FindData): TArchiveFindHandle;
+  const ArchiveFilename, DestDir, Password: String; const RecurseSubDirs,
+  ExtractIntent: Boolean; out FindFileData: TWin32FindData): TArchiveFindHandle;
 begin
   LogArchiveExtractionModeOnce;
 
@@ -1063,6 +1069,11 @@ begin
           ArchiveFindStates := TArchiveFindStates.Create;
         ArchiveFindStates.Add(State);
 
+        { Warn about solid }
+        var Solid: Boolean;
+        if ExtractIntent and GetProperty(State.InArchive, $FFFF, kpidSolid, Solid) and Solid then
+          LogFmt('Archive %s is solid; extraction performance may degrade', [State.ExtractedArchiveName]);
+
         { Finish find data & exit }
         State.FinishCurrentFindData(FindFileData);
         Exit(ArchiveFindStates.Count-1);

+ 1 - 1
Projects/Src/Setup.Install.pas

@@ -1922,7 +1922,7 @@ var
 
       var FindData: TWin32FindData;
       var H := ArchiveFindFirstFileRedir(DisableFsRedir, ArchiveFilename, DestDir,
-        Password, foRecurseSubDirsExternal in CurFile^.Options, FindData);
+        Password, foRecurseSubDirsExternal in CurFile^.Options, True, FindData);
       if H <> INVALID_HANDLE_VALUE then begin
         try
           repeat

+ 2 - 2
Projects/Src/Setup.MainFunc.pas

@@ -1815,7 +1815,7 @@ function EnumFiles(const EnumFilesProc: TEnumFilesProc;
 
     var FindData: TWin32FindData;
     var H := ArchiveFindFirstFileRedir(DisableFsRedir, ArchiveFilename, DestDir,
-      Password, foRecurseSubDirsExternal in CurFile^.Options, FindData);
+      Password, foRecurseSubDirsExternal in CurFile^.Options, False, FindData);
     if H <> INVALID_HANDLE_VALUE then begin
       try
         repeat
@@ -2814,7 +2814,7 @@ var
 
     var FindData: TWin32FindData;
     var H := ArchiveFindFirstFileRedir(DisableFsRedir, ArchiveFilename, '',
-      Password, RecurseSubDirs, FindData);
+      Password, RecurseSubDirs, False, FindData);
     if H <> INVALID_HANDLE_VALUE then begin
       try
         repeat

+ 1 - 1
whatsnew.htm

@@ -124,7 +124,7 @@ issigtool --key-file="MyKey.ispublickey" verify "MyProg.dll"</pre>
       </ul>
       New documentation <a href="https://jrsoftware.org/ishelp/index.php?topic=setup_archiveextraction">ArchiveExtraction</a> topic has a table summarizing the differences between these methods.
     </li>
-    <li>Added new [Files] section flag <tt>extractarchive</tt> and parameter <tt>ExtractArchivePassword</tt>. The supported archive formats, beyond .7z, and the support for password-protected archives, depend on the aforementioned <tt>ArchiveExtraction</tt> directive.<br/>Flags <tt>extractarchive</tt> must be combined with flag <tt>external</tt>, and archive extraction behaves very similar to external file copying. For example, it supports automatic uninstallation of extracted files and can be combined with most other flags and parameters.</li>
+    <li>Added new [Files] section flag <tt>extractarchive</tt> and parameter <tt>ExtractArchivePassword</tt>. The supported archive formats, beyond .7z, and the support for password-protected archives, depend on the aforementioned <tt>ArchiveExtraction</tt> directive.<br/>Flags <tt>extractarchive</tt> must be combined with flag <tt>external</tt>, and archive extraction behaves very similar to external file copying. For example, it supports automatic uninstallation of extracted files and can be combined with most other flags and parameters. Using a solid archive is not recommended; extraction performance may degrade depending on the solid block size.</li>
     <li>Added example script <i>CodeDownloadFiles2.iss</i> to demonstrate how to use a single <tt>[Files]</tt> entry to verify and extract a downloaded archive.</li>
     <li>Archive extraction now honors the file system redirection state set by 64-bit install mode, entry flags, and support function <tt>EnableFsRedirection</tt>.</li>
   </ul>