If the items within the archive are encrypted but the filenames aren't, just call ListFiles and after it returns loop over the items and check their Encrypted
property. If any of them are true prompt the user for the password and assign it afterwards.
If the filenames are encrypted too then no, the stock JCL distribution doesn't support detecting that beforehand. I have a fork of the JCL on github, and the sevenzip_error_handling branch contains a bunch of enhancements/fixes to TJclCompressionArchive
, including the addition of an OnOpenPassword
callback that's called if the filenames are encrypted. With that, the basic load looks like this:
type
TMyObject = class
private
FArchive: TJcl7zDecompressArchive;
FEncryptedFilenames: Boolean;
procedure GetOpenPassword(Sender: TObject;
var APassword: WideString): Boolean;
public
procedure OpenArchive;
end;
...
procedure TMyObject.GetOpenPassword(Sender: TObject;
var APassword: WideString): Boolean;
var
Dlg: TPasswordDialog;
begin
Dlg := TPasswordDialog.Create(nil);
try
Result := Dlg.ShowModal = mrOk;
if Result then
begin
FEncryptedFilenames := True;
FArchive.Password := Dlg.Password;
end;
finally
Dlg.Free;
end;
end;
...
procedure TMyObject.OpenArchive;
begin
FArchive := TJcl7zUpdateArchive.Create(Filename);
FArchive.OnOpenPassword := GetOpenPassword;
while True do
begin
FEncryptedFilenames := False;
try
FArchive.ListFiles;
Break;
except
on E: EJclCompressionFalse do
if FEncryptedFilenames then
// User probably entered incorrect password, loop
else
raise;
end;
end;
end;