Sign in to follow this  
Followers 0
wkeeter

FileCopy with a Progressbar

14 posts in this topic

I have searched these forums over and over to try and find a sample of how to copy a single file with a progressbar in a GUI. I see it brought up a lot, but no one offers a solution.

I see there are solutions for a Directory to Directory copy or move.

Is there a way for this to happpen in the GUI?

Share this post


Link to post
Share on other sites



Check this post by livewire


AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

Yeah i tried that one to but didn't work inside a GUI. I did get it to work just as a script.

So i'm still a lookin. :whistle:

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Again will not work for a single file. This is for a directory of files and the more the better it works. The caculation for the progress bar isn't passed until the end of the filecopy, and on a single file it is over with and no progress can be seen becuse it is done.

Just not what I need for a single file copy in the GUI interface.

I do thank you for looking though. I have seen all of this stuff when I was searching. But i can't find anything on copying a single file with a progress bar that actually works.

Edited by wkeeter

Share this post


Link to post
Share on other sites

the code is

"_test("E:\music\new\hell.avi","E:\")

Func _test($fromFile,$tofile)

Local $FOF_RESPOND_YES = 16

Local $FOF_SIMPLEPROGRESS = 256

$winShell = ObjCreate("shell.application")

$winShell.namespace($tofile).CopyHere($fromFile,$FOF_RESPOND_YES)

EndFunc"

you can copy this code to scite and press Alt+F5 to beta run it .

uh,i tried a song ,but my PC is too fast , then i tried a movie,ok, i saw the progress bar:)

good luck

Share this post


Link to post
Share on other sites

the code is

"_test("E:\music\new\hell.avi","E:\")

Func _test($fromFile,$tofile)

Local $FOF_RESPOND_YES = 16

Local $FOF_SIMPLEPROGRESS = 256

$winShell = ObjCreate("shell.application")

$winShell.namespace($tofile).CopyHere($fromFile,$FOF_RESPOND_YES)

EndFunc"

you can copy this code to scite and press Alt+F5 to beta run it .

uh,i tried a song ,but my PC is too fast , then i tried a movie,ok, i saw the progress bar:)

good luck

This is a Windows Copy Box with a progress bar not a GUI Progress bar this isn't what I'm looking for. But thanks!

Share this post


Link to post
Share on other sites

Well as i see no one is offering any other information i'm taking it that this just can't be done at this time with autoit. And again this subject will go under the carpet unresolved.

But thanks guys that did offer information!

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Well as i see no one is offering any other information i'm taking it that this just can't be done at this time with autoit. And again this subject will go under the carpet unresolved.

But thanks guys that did offer information!

It's quite simple only nobody did it.

I did it in my very old Delphi project, here is piece of code from it:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Gauges, StdCtrls, ExtCtrls,
  glob_prom;

const UM_START = WM_USER + 1;

type
  TPole = array[1..65535] of Byte;
  PPole = ^TPole;

  TForm1 = class(TForm)
    bt_storno: TButton;
    t1: TLabel;
    t2: TLabel;
    t_co: TLabel;
    t_kam: TLabel;
    Gauge1: TGauge;
    Gauge2: TGauge;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure bt_stornoClick(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    Buf:PPole;
    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
    procedure AppException(Sender: TObject; E: Exception);
    procedure Delej(var Message: TMessage); message UM_START;
    procedure Kopiruj(S1,S2:string;Size,datum:integer);
    procedure Aktualizuj(H1,H2:integer);
    function VytvorAdr(Adr:string):boolean;
  public
  end;

var
  Form1: TForm1;

implementation

uses FileCtrl;

{$R *.DFM}


procedure TForm1.FormCreate(Sender: TObject);
begin
  New(Buf);
  Application.OnException := AppException;
  Form1.Caption := Format('Záloha - %s',[VstParam]);
  PostMessage(Form1.handle,UM_START,0,0);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Dispose(Buf);
end;

procedure TForm1.WMSysCommand(var Message: TWMSysCommand);
begin
  if (Message.CmdType and $FFF0 = SC_KEYMENU) or
     (Message.CmdType and $FFF0 = SC_MOUSEMENU) then Exit;
  inherited;
end;

procedure TForm1.AppException(Sender: TObject; E: Exception);
begin
  Application.ShowException(E);
  Application.Terminate;
end;

procedure TForm1.Delej;
var I : integer;
begin
  for I := 1 to DelkaPole do
  begin
    if pole[I,3] > '0' then
      Kopiruj(pole[I,1],pole[I,2],StrToInt(pole[I,3]),StrToInt(pole[I,4]));
    Application.ProcessMessages;
    if Application.Terminated then Break;
  end;
  Application.Terminate;
end;

procedure TForm1.Kopiruj(S1,S2:string;Size,datum:integer);
var f1,f2 : file;
    I,Handle,Time,NumRead,NumWritten,Hotovo : integer;
    CilAdr : string;
begin
  Aktualizuj(0,Round(CelkHotovo/CelkSize*100));
  t_co.Caption := S1;
  t_kam.Caption := S2;
  I := Length(S2);
  while S2[I] <> '\' do Dec(I);
  CilAdr := Copy(S2,1,I);
  if not VytvorAdr(CilAdr) then
  begin
    Application.MessageBox(PChar('Nelze vytvořit adresář ' + CilAdr),PChar('Záloha ' + verze),0{MB_OK});
    Application.Terminate;
    Exit;
  end;
  Hotovo := 0;
  AssignFile(f1,S1);
  FileMode := 0;  {Set file access to read only }
  Reset(f1,1);
  AssignFile(f2,S2);
  Rewrite(f2,1);
  repeat
    BlockRead(f1, Buf^, 65535, NumRead);
    BlockWrite(f2, Buf^, NumRead, NumWritten);
    Inc(Hotovo,NumWritten);
    Inc(CelkHotovo,NumWritten);
    Aktualizuj(Round(Hotovo/Size*100), Round(CelkHotovo/CelkSize*100));
    Application.ProcessMessages;
    if Application.Terminated then Break;
  until (NumRead < 65535);
  CloseFile(f1);
  CloseFile(f2);

  // po predcasnem ukonceni
  if Hotovo < Size then
    DeleteFile(S2)
  else
  begin
    // nastaveni stejneho casu u S2 dle S1
    Time := FileAge(S1);
    Handle := FileOpen(S2, fmOpenWrite);
    if Handle > 0 then
    begin
      FileSetDate(Handle, Time);
      FileClose(Handle);
    end;
  end;
end;

procedure TForm1.bt_stornoClick(Sender: TObject);
begin
  Application.Terminate;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 if Key = VK_ESCAPE then bt_stornoClick(Sender);
end;

procedure TForm1.Aktualizuj(H1,H2:integer);
begin
  Gauge1.Progress := H1;
  Gauge2.Progress := H2;
  Application.Title := Format('%d%% - Záloha',[H2]);
end;

// vytvori adresar i s podadresari
// napr: C:\aaa\123\abc\
// musi byt uvedena cela cesta! a jako posl. znak '\'
function TForm1.VytvorAdr(Adr:string):boolean;
var S:string;
    I,K:integer;
begin
  Result := true;
  K := Length(Adr);
{  if Adr[K] <> '\' then
  begin
    Adr := Adr + '\';
    Inc(K);
  end;}
  I := 3;
  repeat
    S := Copy(Adr,1,I);
    if not DirectoryExists(S) then
      if not CreateDir(S) then
      begin
        Result := false;
        Break;
      end;
    I := I + Pos('\',Copy(Adr,I+1,K));
  until (S = Adr);
end;

end.

Core for your needs is:

AssignFile(f1,S1);
  FileMode := 0;  {Set file access to read only }
  Reset(f1,1);
  AssignFile(f2,S2);
  Rewrite(f2,1);
  repeat
    BlockRead(f1, Buf^, 65535, NumRead);
    BlockWrite(f2, Buf^, NumRead, NumWritten);
    Inc(Hotovo,NumWritten);
    Inc(CelkHotovo,NumWritten);
    Aktualizuj(Round(Hotovo/Size*100), Round(CelkHotovo/CelkSize*100));
    Application.ProcessMessages;
    if Application.Terminated then Break;
  until (NumRead < 65535);
  CloseFile(f1);
  CloseFile(f2);

procedure TForm1.Aktualizuj(H1,H2:integer);
begin
  Gauge1.Progress := H1;
  Gauge2.Progress := H2;
  Application.Title := Format('%d%% - Záloha',[H2]);
end;

So just look at principle and write something similar in Autoit yourself ...

--> instead of Gauge use ProgressBar

Edited by Zedna

Share this post


Link to post
Share on other sites

You can try the following code.

I think it will give you what you need to craft what you want.

;copy with progress
;Steve Podhajecki [eltorro] gehossafats@netmdc.com
#include <GUIConstants.au3>
#Include <APIFileReadWrite.au3>
Local $Source = "C:\Program Files\AutoIt3\AU3Info.exe"
Local $Dest = "C:\AU3Info.exe"
CopyWithProg($Source,$Dest)
Exit

Func CopyWithProg($szSource, $szDest)
    if $szSource ="" or $szDest ="" then
        SetError(1)
        Return 0
    EndIf
    

Local $Progress1 = GUICtrlCreateProgress(8, 56, 417, 25)
Local $Form1 = GUICreate("Copy File", 369, 128, 193, 126)
Local $lblProgress = GUICtrlCreateLabel("", 8, 16,355, 25)
Local $Progress1 = GUICtrlCreateProgress(8, 56, 353, 17)
Local $btnProgress = GUICtrlCreateButton("Close", 136, 88, 75, 25, 0)
GUICtrlSetState($btnProgress,$GUI_DISABLE)
GUISetState(@SW_SHOW)
; get file size
Local $iProgress = FileGetSize($szSource)
;figure Number of 1k reads
If $iProgress >1024 Then $iProgress = $iProgress / 1024
Local $x,$pos,$retv
    ;open source file
    $hSource = FileOpen($szSource,0)
     if $hSource = 0 then Return SetError(2)
     ;open dest file overwrite or create if not exist
     $hDest = FileOpen($szDest,10)
     if $hDest =0  Then
         FileClose($hSource)
         Return SetError(3)
     EndIf
     GUICtrlSetData($lblProgress,"Copying "&$szSource&" to "&$szDest)
     While 1
         ;read 1k blocks
         $hSourceData =FileRead($hSource,1024)
         if @error = -1 then
             ;write the last block
             $retv= FileWrite($hDest,($hSourceData))
             GUICtrlSetData($lblProgress,"Done.")
             ExitLoop
         EndIf
        ;increment progress bar
         $pos = $pos +(100/$iProgress)
         GUICtrlSetData($Progress1,$pos)
         if $iProgress <100 Then sleep(10) ; slow down progress so it can be seen
         ;write block
         $retv= FileWrite($hDest,($hSourceData))
    WEnd
     FileClose($hSource)
     FileClose($hDest)
     GUICtrlSetState($btnProgress,$GUI_ENABLE)
     While 1
         Local $prgMsg = GUIGetMsg()
         if $prgMsg = $GUI_EVENT_CLOSE or $prgMsg= $btnProgress Then ExitLoop
        sleep(10)
    WEnd
 GUIDelete($Form1)    
 EndFunc

Hope this helps.

eltorro

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Hey mate

Couly you please post the #include file <APIFileReadWrite.au3> ?

Cheers

Edited by lyledg

Share this post


Link to post
Share on other sites

Just so you know, for the purpose of his example script you don't actually need that include (I copied the script, commented out that #include cus I don't have it either, and it worked fine). You can also comment out line 51

if $iProgress <100 Then sleep(10); slow down progress so it can be seen
when you go to use it in a real application. :whistle:

Share this post


Link to post
Share on other sites

Hi This is just what I have been looking for, although when I run the script it pauses and will not start again. If I click the system tray icon I get Pause (with a tick next to it) and exit.

Clicking pause does nothing and clicking exit closes the script.

Any ideas?

Share this post


Link to post
Share on other sites

Code works great, thanks.

However, what if executing something else like calling an application installation from a ShellExecute?

How can I monitor and report the progression to a progress control?

TIA

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0