Delphi JEDI JCL JclCompression:检测受密码保护的存档
Posted
技术标签:
【中文标题】Delphi JEDI JCL JclCompression:检测受密码保护的存档【英文标题】:Delphi JEDI JCL JclCompression: Detect password-protected archive 【发布时间】:2014-02-14 16:14:51 【问题描述】:您能否从 JEDI 代码库 (JCL) 中检测出档案是否受 JclCompression 的密码保护?我想提取各种档案,但显然我不想显示密码提示,除非档案需要密码。我可以正确设置密码,只是无法检测存档是否需要密码。以下 SO 帖子显示了如何设置密码:
Using 7-Zip from Delphi?
该选项可能不存在,因为该过程中有一个 TODO 似乎获取归档属性,例如 ipEncrypted
(来自 JCL 2.5):
procedure TJclDecompressItem.CheckGetProperty(
AProperty: TJclCompressionItemProperty);
begin
// TODO
end;
【问题讨论】:
你为什么不选择一流的 tpAbbreviaJCL
是一个不正确的标签,它指的是完全不同的东西。
@DavidHeffernan 据我了解,不支持 7-Zip、RAR 以及 7z.dll 支持的许多其他内容。
【参考方案1】:
如果存档中的项目已加密但文件名未加密,则只需调用 ListFiles 并在它返回后循环遍历项目并检查其Encrypted
属性。如果其中任何一个为真,则提示用户输入密码并在之后分配。
如果文件名也被加密,那么不会,股票 JCL 发行版不支持预先检测。我有一个fork of the JCL on github,sevenzip_error_handling 分支包含对TJclCompressionArchive
的一系列增强/修复,包括添加一个OnOpenPassword
回调,如果文件名被加密则调用。这样,基本负载如下所示:
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;
【讨论】:
谢谢,我还没有尝试过 JCL 分支,但是TJclCompressionItem
Encrypted
属性可以工作。
克雷格,终于可以尝试分叉了——适用于我的文件名加密的受密码保护的档案的测试用例。非常感谢。以上是关于Delphi JEDI JCL JclCompression:检测受密码保护的存档的主要内容,如果未能解决你的问题,请参考以下文章
JclUnicode.pas(8000行),JclAnsiStrings.pas(4000行),JclWideStrings.pas(2300行),JclStrings.pas(5400行),JclC