Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Copying a folder with it's contents and subfolders

1,082 views
Skip to first unread message

Dan

unread,
Apr 2, 2008, 6:27:29 PM4/2/08
to
I'm trying to do something fairly simple. I just need to copy a folder
along with all it's contents to another location. Unfortunately the only
way I can find to do it is some huge recursive procedure. Isn't there a
simple Delphi command to copy/move folder with contents?

Or failing that is there a simple, and clean recursive script which I can
use to copy the folder & files?

- Dan

Dan

unread,
Apr 2, 2008, 7:13:02 PM4/2/08
to
I just tried SHFileOperation and I can't get that to work either. Is there
some problem wrong with my code? The destination folder structure doesn't
exist yet when I run this code, don't know if that's a factor or not.

var
OpStruct: TSHFileOpStruct;
begin
AppendStr(FromDir, #0);
AppendStr(Destination, #0);
With OpStruct Do
Begin
Wnd:=0;
wFunc:=FO_COPY;
pFrom:= @FromDir[1];
pTo:= @Destination[1];
fFlags:=FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION;
End;
if not DirectoryExists(Destination) then ForceDirectories(Destination);
SHFileOperation(OpStruct);
end;

"Dan" <froze...@gmail.com> wrote in message
news:47f40868$1...@newsgroups.borland.com...

Dan

unread,
Apr 2, 2008, 8:06:47 PM4/2/08
to
Unfortunately if you look at the message I replied to myself, it shows how I
tried SHFileOperation and I can't get it to work. It's simple code, but no
folders are copied. I get the error that the file could not be found.
Which doesn't make sense since I'm copying a folder.

- Dan

"Rob Kennedy" <m...@privacy.net> wrote in message
news:47f41c86$1...@newsgroups.borland.com...


> Dan wrote:
>> I'm trying to do something fairly simple. I just need to copy a folder
>> along with all it's contents to another location.
>

> You'd think that would be simple, wouldn't you? But do you want to copy
> the file permissions, too? What if the permissions aren't compatible with
> the ones in the destination folder? What should you do if a file is
> encrypted? If one of the folders is a hard link, should you duplicate the
> link, or make a new copy of the linked-to folder? What should the new
> files' dates be?


>
>> Unfortunately the only way I can find to do it is some huge recursive
>> procedure. Isn't there a simple Delphi command to copy/move folder with
>> contents?
>

> ShFileOperation can copy files and folders the same as if you had dragged
> and dropped them in Windows Explorer. Explorer's answers to the questions
> above might not be what you want.


>
>> Or failing that is there a simple, and clean recursive script which I can
>> use to copy the folder & files?
>

> Sounds like you already have that.
>
> --
> Rob

Rob Kennedy

unread,
Apr 2, 2008, 8:06:19 PM4/2/08
to
Dan wrote:
> I just tried SHFileOperation and I can't get that to work either.

You need to elaborate. What doesn't work about it? Can you compile it?
Can you run it? When you run it, what happens? What did you expect to
happen instead?

> Is
> there some problem wrong with my code? The destination folder structure
> doesn't exist yet when I run this code, don't know if that's a factor or
> not.

Test your function when the destination folder _does_ exist, and then
you'll know whether it's a factor.

> var
> OpStruct: TSHFileOpStruct;
> begin
> AppendStr(FromDir, #0);
> AppendStr(Destination, #0);

Is AppendStr a Delphi function? It's more idiomatic to write a regular
string-append statement:

FromDir := FromDir + #0;

> With OpStruct Do
> Begin
> Wnd:=0;
> wFunc:=FO_COPY;
> pFrom:= @FromDir[1];
> pTo:= @Destination[1];

I'd write those like this:

pFrom := PChar(FromDir);

Do those strings specify fully qualified paths? The documentation
recommends it.

> fFlags:=FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION;

TShFileOpStruct has eight members, but you only touch five of them. What
about the other three?

> End;
> if not DirectoryExists(Destination) then ForceDirectories(Destination);

I'm pretty sure ForceDirectories already incorporates the
DirectoryExists call; you don't need to call it yourself.

> SHFileOperation(OpStruct);

You're ignoring the function's return value. The return value tells you
why the function failed.

> end;

--
Rob

Rob Kennedy

unread,
Apr 2, 2008, 7:53:42 PM4/2/08
to
Dan wrote:
> I'm trying to do something fairly simple. I just need to copy a folder
> along with all it's contents to another location.

You'd think that would be simple, wouldn't you? But do you want to copy

the file permissions, too? What if the permissions aren't compatible
with the ones in the destination folder? What should you do if a file is
encrypted? If one of the folders is a hard link, should you duplicate
the link, or make a new copy of the linked-to folder? What should the
new files' dates be?

> Unfortunately the

> only way I can find to do it is some huge recursive procedure. Isn't
> there a simple Delphi command to copy/move folder with contents?

ShFileOperation can copy files and folders the same as if you had

dragged and dropped them in Windows Explorer. Explorer's answers to the
questions above might not be what you want.

> Or failing that is there a simple, and clean recursive script which I

> can use to copy the folder & files?

Sounds like you already have that.

--
Rob

Rob Kennedy

unread,
Apr 2, 2008, 8:18:40 PM4/2/08
to
Dan wrote:
> Unfortunately if you look at the message I replied to myself, it shows
> how I tried SHFileOperation and I can't get it to work. It's simple
> code, but no folders are copied. I get the error that the file could
> not be found. Which doesn't make sense since I'm copying a folder.

Pretend it said the _folder_ could not be found; does it make sense now?

--
Rob

Dan

unread,
Apr 2, 2008, 8:15:56 PM4/2/08
to
> You need to elaborate. What doesn't work about it? Can you compile it? Can
> you run it? When you run it, what happens? What did you expect to happen
> instead?

It compiles fine, when I run the code it runs fine and tries to copy. The
SHFileOperation function returns an integer of 2. I'm not really sure which
error code that corrisponds to though.

>
> Test your function when the destination folder _does_ exist, and then
> you'll know whether it's a factor.

Whether the destination folder is there or not nothing ever copies.

I revised the code to:

FillChar (shf, SizeOf (shf), #0);
fromStr:= source + #0#0;
toStr:= dest + #0#0;
shf.Wnd:= 0;
shf.wFunc:= FOF_COPY;
shf.pFrom:= PCHAR (fromStr);
shf.pTo:= PCHAR (toStr);
shf.fFlags:= flags;
SHFileOperation (shf);

> Do those strings specify fully qualified paths? The documentation
> recommends it.

Yes, it's an exact path eg. C:\Documents and ...

>> fFlags:=FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION;
>
> TShFileOpStruct has eight members, but you only touch five of them. What
> about the other three?

I'm not sure what these other "members are".

> --
> Rob

Iain Macmillan

unread,
Apr 3, 2008, 1:35:14 AM4/3/08
to
In article <47f421d3$1...@newsgroups.borland.com>, "Dan" <froze...@gmail.com>
wrote:

>> Do those strings specify fully qualified paths? The documentation
>> recommends it.
>
> Yes, it's an exact path eg. C:\Documents and ...

If it's got spaces in the path shouldn't it be:

"C:\Documents and ..."

Rob Kennedy

unread,
Apr 3, 2008, 2:53:31 AM4/3/08
to

I don't see why. The quotes are for escaping command-line processing.
The API already knows it's getting one file name per list item.

--
Rob

Andrew Jameson

unread,
Apr 3, 2008, 6:55:10 AM4/3/08
to

"Dan" <froze...@gmail.com> wrote in message
news:47f40868$1...@newsgroups.borland.com...

Hi Dan,
It's been a while since I wrote / used this procedure - SHFileOperation is
very fussy about null terminators and its TShFileOpStruct ... get anything
wrong and it either fails silently or works but not as expected or wanted.

Andrew

function ShFilesOperation(Source, Destination : string; SHFlags :
FILEOP_FLAGS; SHFunc : integer) : boolean;
{ FOF_ALLOWUNDO - Preserves undo information, if possible.
FOF_CONFIRMMOUSE - Not implemented.
FOF_FILESONLY - Performs the operation only on files if a wildcard
filename (*.*) is specified.
FOF_MULTIDESTFILES - Indicates that the pTo member specifies multiple
destination files (one for each source file)
rather than one directory where all source files
are to be deposited.
FOF_NOCONFIRMATION - Responds with "yes to all" for any dialog box that
is displayed.
FOF_NOCONFIRMMKDIR - Does not confirm the creation of a new directory if
the operation requires one to be created.
FOF_NOERRORUI - Do not put up error UI.
FOF_RENAMEONCOLLISION - Gives the file being operated on a new name (such
as "Copy #1 of...") in a move, copy,
or rename operation if a file of the target name
already exists.
FOF_SILENT - Does not display a progress dialog box.
FOF_SIMPLEPROGRESS - Displays a progress dialog box, but does not show
the filenames.
FOF_WANTMAPPINGHANDLE - Fills in the hNameMappings member. The handle must
be freed by using the SHFreeNameMappings function. }
var
ShFileOpStruct : TShFileOpStruct;
begin
if (SHFunc = FO_DELETE) then
Source := ExcludeTrailingBackslash(Source);
FillChar(ShFileOpStruct, SizeOf(ShFileOpStruct), #0);
with ShFileOpStruct do begin
Wnd := Application.Handle;
wFunc := SHFunc;
fFlags := SHFlags;
pFrom := PChar(Source + #0);
pTo := PChar(Destination + #0);
end; {with}
Result := (SHFileOperation(ShFileOpStruct) = 0); //
Success if returns zero.
Result := Result and not ShFileOpStruct.fAnyOperationsAborted; //
Not a success if it got aborted.

end; {ShFilesOperation}


Remy Lebeau (TeamB)

unread,
Apr 3, 2008, 1:01:07 PM4/3/08
to

"Dan" <froze...@gmail.com> wrote in message
news:47f421d3$1...@newsgroups.borland.com...

> It compiles fine, when I run the code it runs fine and tries to copy.
> The SHFileOperation function returns an integer of 2. I'm not
> really sure which error code that corrisponds to though.

2 = ERROR_FILE_NOT_FOUND


Gambit


0 new messages