Witam, mam pewien problem przerobiłem sobie procedury z unrarexample, ale jak daję w pętli for to tak jakby jej nie wykonywało. Zamieszczam kody:
unrar.dcu
unit unrar;
{$ALIGN OFF}
interface
uses Windows;
const
ERAR_END_ARCHIVE = 10;
ERAR_NO_MEMORY = 11;
ERAR_BAD_DATA = 12;
ERAR_BAD_ARCHIVE = 13;
ERAR_UNKNOWN_FORMAT = 14;
ERAR_EOPEN = 15;
ERAR_ECREATE = 16;
ERAR_ECLOSE = 17;
ERAR_EREAD = 18;
ERAR_EWRITE = 19;
ERAR_SMALL_BUF = 20;
RAR_OM_LIST = 0;
RAR_OM_EXTRACT = 1;
RAR_SKIP = 0;
RAR_TEST = 1;
RAR_EXTRACT = 2;
RAR_VOL_ASK = 0;
RAR_VOL_NOTIFY = 1;
RAR_DLL_VERSION = 2;
UCM_CHANGEVOLUME = 0;
UCM_PROCESSDATA = 1;
type
TRARHeaderData = record
ArcName,
FileName: array[0..Pred(260)] of Char;
Flags,
PackSize,
UnpSize,
HostOS,
FileCRC,
FileTime,
UnpVer,
Method,
FileAttr: UINT;
CmtBuf: PChar;
CmtBufSize,
CmtSize,
CmtState: UINT;
end;
TRAROpenArchiveData = record
ArcName: PChar;
OpenMode,
OpenResult: UINT;
CmtBuf: PChar;
CmtBufSize,
CmtSize,
CmtState: UINT;
end;
TUnrarCallback = function (Msg: UINT; UserData, P1, P2: Integer) :Integer; stdcall;
TRAROpenArchive = function (var ArchiveData: TRAROpenArchiveData): THandle; stdcall;
TRARCloseArchive = function (hArcData: THandle): Integer; stdcall;
TRARReadHeader = function (hArcData: THandle; var HeaderData: TRARHeaderData): Integer; stdcall;
TRARProcessFile = function (hArcData: THandle; Operation: Integer; DestPath, DestName: PChar): Integer; stdcall;
TRARSetCallback = procedure (hArcData: THandle; UnrarCallback: TUnrarCallback; UserData:Integer); stdcall;
TRARSetPassword = procedure (hArcData: THandle; Password: PChar); stdcall;
TRARGetDllVersion = function: integer; stdcall;
// Wrapper for DLL's function - old unrar.dll doesn't export RARGetDllVersion
// Returns: -1 = DLL not found; 0 = old ver. (C-style callbacks); >0 = new ver.
function RARDllGetVersion: integer;
// Dynamic loading of DLL
function UnrarDllLoad(dllfilename : string) : Boolean;
procedure UnrarDllUnload;
var
UnrarDllHandle : THandle;
RAROpenArchive : TRAROpenArchive;
RARCloseArchive : TRARCloseArchive;
RARReadHeader : TRARReadHeader;
RARProcessFile : TRARProcessFile;
RARSetPassword : TRARSetPassword;
RARSetCallback : TRARSetCallback;
implementation
var
RARGetDllVersion : TRARGetDllVersion;
function RARDllGetVersion: integer;
begin
if @RARGetDllVersion=nil then
Result:= 0
else
Result:= RARGetDllVersion;
end;
// Return: True = success
function UnrarDllLoad(dllfilename : string) : Boolean;
var
r : Boolean;
begin
r:=False;
try
UnrarDllHandle := LoadLibrary(PChar(dllfilename));
if UnrarDllHandle <> 0 then
begin
@RAROpenArchive := GetProcAddress(UnrarDllHandle, 'RAROpenArchive');
@RARCloseArchive := GetProcAddress(UnrarDllHandle, 'RARCloseArchive');
@RARReadHeader := GetProcAddress(UnrarDllHandle, 'RARReadHeader');
@RARProcessFile := GetProcAddress(UnrarDllHandle, 'RARProcessFile');
@RARSetPassword := GetProcAddress(UnrarDllHandle, 'RARSetPassword');
@RARSetCallback := GetProcAddress(UnrarDllHandle, 'RARSetCallback');
@RARGetDllVersion := GetProcAddress(UnrarDllHandle, 'RARGetDllVersion');
if (@RAROpenArchive = nil) or (@RARCloseArchive = nil) or
(@RARReadHeader = nil) or (@RARProcessFile = nil) or
(@RARSetPassword = nil) or (@RARSetCallback = nil) then
FreeLibrary(UnrarDllHandle)
else
r:=True;
end;
except
end;
Result:=r;
end;
procedure UnrarDllUnload;
begin
if UnrarDllHandle <> 0 then
FreeLibrary(UnrarDllHandle);
end;
end.
Projekt:
...
uses Unrar
...
type
CharMAX_PATH = array [0..MAX_PATH] of char;
procedure Wypakuj(pliksciezka:String; docsiezka:String);
...
var
frmUnrar: TForm1;
RAROpenArchiveData: TRAROpenArchiveData;
RARHeaderData: TRARHeaderData;
RARExtract: boolean;
RARComment: CharMAX_PATH;
RARPwd: array [0..80] of char;
RARFileName: CharMAX_PATH;
RARStartTime: TDateTime;
RARElapsedTime: TDateTime;
iRARDoneTime: integer;
iRAREsti: integer;
RARPctDone: integer;
RarDllLoaded: boolean;
RARPctLeft: integer;
Hour, Min, Sec, MSec: word;
lKBytesDone: longint;
lTotalSize: longint;
PctRemain: longint;
lKBWritten: longint;
ArchivePwd: string;
InstallCancel: Boolean;
...
////////////////////////////////////////////////////////////////////////
function RarCallbackProc(msg: UINT; UserData, P1, P2: integer): integer; stdcall;
var
s: string;
begin
Result := 0;
case msg of
UCM_CHANGEVOLUME:
if (P2 = RAR_VOL_ASK) then
begin
end;
UCM_PROCESSDATA:
begin
if RARExtract then
begin
lKBytesDone := lKBytesDone + P2;
frmUnrar.Refresh;
Application.ProcessMessages;
lKBWritten := lKBWritten + (P2 div 1024);
frmUnrar.ProgressBar1.Position := lKBWritten;
frmUnrar.Label1.Caption :='Wypakowywuję: '+IntToStr(lKBWritten) +
' z ' + IntToStr(lTotalSize) + ' KB';
if lTotalSize > 0 then
begin
RARPctDone := (lKBWritten * 100) div lTotalSize;
if RARPctDone = 0 then RARPctDone := 1;
end
else
RARPctDone := 50;
frmUnrar.Refresh;
Application.ProcessMessages;
Result := 1;
end
else
Result := 1;
end;
end;
end;
////////////////////////////////////////////////////////////////////////
function a2o(const s: string): string;
begin
SetLength(Result, Length(s));
AnsiToOemBuff(PChar(S), PChar(Result), Length(s));
end;
////////////////////////////////////////////////////////////////////////
procedure TForm1.Wypakuj(pliksciezka:String; docsiezka:String);
var
s: string;
j: longint;
RARrc: integer;
RARhnd: THandle;
A: CharMAX_PATH;
sDir: string;
PDestPath: CharMAX_PATH;
Mode: integer;
begin
if FileExists(pliksciezka) then
begin
// Button1.Enabled:=True;
RAROpenArchiveData.OpenResult := 99;
StrPCopy(@RARFileName, pliksciezka);
RAROpenArchiveData.ArcName := @RARFileName;
RAROpenArchiveData.OpenMode := RAR_OM_LIST;
RAROpenArchiveData.CmtBuf := @RARComment;
RAROpenArchiveData.CmtBufSize := 255;
RARhnd := RAROpenArchive(RAROpenArchiveData);
if RAROpenArchiveData.OpenResult <> 0 then
begin
case RAROpenArchiveData.OpenResult of
ERAR_NO_MEMORY: s := 'Not enough memory to initialize data structures';
ERAR_BAD_DATA: s := 'Archive header broken';
ERAR_BAD_ARCHIVE: s := 'File is not valid RAR archive';
ERAR_EOPEN: s := 'File open error';
end;
MessageDlg('Unable to open rar archive: ' + s + '!', mtError, [mbOK], 0);
Exit;
end
else
begin
if ArchivePwd <> '' then // set pwd if specified
RARSetPassword(RARhnd, @RARPwd);
RARHeaderData.UnpSize := 0;
s := 'c:\';
StrPCopy(@A, s);
repeat
RARrc := RARReadHeader(RARhnd, RARHeaderData);
if RARrc = 0 then
begin
RARrc := RARProcessFile(RARhnd, RAR_SKIP, @A, @A);
j := RARHeaderData.UnpSize div 1024;
lTotalSize := lTotalSize + j;
end
else if (RARrc <> 0) and (RARrc <> ERAR_END_ARCHIVE) then
begin
MessageDlg('Header file broken!', mtError, [mbOK], 0);
Exit;
end;
until RARrc <> 0;
if RARCloseArchive(RARhnd) <> 0 then
begin
MessageDlg('Unable to close rar archive!', mtError, [mbOK], 0);
Exit;
end;
end;
end;
InstallCancel:=False;
RARExtract := True;
Mode := RAR_OM_EXTRACT;
lKBWritten := 0;
frmUnrar.ProgressBar1.Position := 0;
frmUnrar.ProgressBar1.Max := lTotalSize;
RARStartTime := Time;
RAROpenArchiveData.OpenResult := 99;
RAROpenArchiveData.OpenMode := Mode;
RAROpenArchiveData.ArcName := @RARFileName;
RAROpenArchiveData.CmtBuf := @RARComment;
RAROpenArchiveData.CmtBufSize := 255;
RARhnd := RAROpenArchive(RAROpenArchiveData);
if RAROpenArchiveData.OpenResult <> 0 then
begin
case RAROpenArchiveData.OpenResult of
ERAR_NO_MEMORY: s := 'Not enough memory to initialize data structures';
ERAR_BAD_DATA: s := 'Archive header broken';
ERAR_BAD_ARCHIVE: s := 'File is not valid RAR archive';
ERAR_EOPEN: s := 'File open error';
end;
MessageDlg('Unable to open rar archive: ' + s + '!', mtError, [mbOK], 0);
Exit;
end;
if ArchivePwd <> '' then // set pwd if specified
RARSetPassword(RARhnd, @RARPwd);
RARSetCallback(RARhnd, RarCallbackProc, integer(@Mode));
StrPCopy(@PDestPath, a2o(docsiezka));
sDir := docsiezka;
if sDir[Length(sDir)] <> '\' then
sDir := sDir + '\';
repeat
RARrc := RARReadHeader(RARhnd, RARHeaderData);
if RARrc <> ERAR_END_ARCHIVE then
begin
s := StrPas(RARHeaderData.FileName);
lKBytesDone := 0;
frmUnrar.Refresh;
Application.ProcessMessages;
end;
if RARrc = 0 then
RARrc := RARProcessFile(RARhnd, RAR_EXTRACT, @PDestPath, nil);
if (RARrc <> 0) and (RARrc <> ERAR_END_ARCHIVE) then
begin
if (RARrc = 12) or (RARrc = 16) then
begin
if FileExists(sDir + s) then
begin
if (FileGetAttr(sDir + s)) and (faReadOnly) = 1 then
begin
MessageDlg('Unable to overwrite ' + sDir + s + '!', mtError, [mbOK], 0);
end;
RARrc := RARProcessFile(RARhnd, RAR_EXTRACT, @PDestPath, nil);
end;
end;
if (RARrc = 12) then
begin
MessageDlg('An Error occured during extracting of ' + s + '!' + #13#10 +
'RARProcessFile: ' + IntToStr(RARrc), mtError, [mbOK], 0);
Exit;
end
else
RARrc := 0;
end;
Application.ProcessMessages;
until (RARrc <> 0) or (InstallCancel);
if InstallCancel then
MessageDlg('Unpacking aborted by user!', mtInformation, [mbOK], 0);
if RARCloseArchive(RARhnd) <> 0 then
begin
MessageDlg('Unable to close rar archive!', mtError, [mbOK], 0);
end;
end;
////////////////////////////////////////////////////////////////////////
...
procedure TForm1.Button1Click(Sender: TObject);
begin
for ii:=0 to ListBox1.Count-1 do
begin
wypakuj(ExtractFilePath(Application.ExeName)+StringReplace(ListBox2.Items.Strings[0], '/', '\', [rfReplaceAll])+'.rar', 'D:\');
lTotalSize:=0;
Progressbar2.Position:=ProgressBar2.Position+1;
try
DeleteFile(ExtractFilePath(Application.ExeName)+ListBox2.Items.Strings[0]+'.rar');
except
Memo1.Lines.Add('Błąd!')
end;
ListBox2.Items.Delete(0);
end;
Label1.Caption:='Koniec!';
end;
Z góry dziękuję za pomoc!