Solved

File Shell Operations

Posted on 2001-07-27
6
1,035 Views
Last Modified: 2007-12-19
Hi, I'm trying to use the
 
 SHFileOperation function (in unit ShellAPI).

What I want to accomplish is:
1) SHMoveFile(SourceFile, TargetFile: String): Boolean;

2) SHCopyFile(SourceFile, TargetFile: String): Boolean;

This is my current code:

-------- BEGIN CODE SNIPPET ------------

function SHOper(Operator: Cardinal; const SourceFile, TargetFile: String): Boolean;
var
 Info: TSHFileOpStruct;

begin
 with Info do begin
  Wnd := frmSort.Handle;
  wFunc := Operator;
  pFrom := PChar(SourceFile);
  pTo := PChar(TargetFile);
  fFlags := FOF_ALLOWUNDO;
 end;

 Result := (SHFileOperation(Info) = 0);
end;

function SHCopyFile(const SourceFile, TargetFile: string): Boolean;
begin
 Result := SHOper(FO_COPY, SourceFile, TargetFile);
end;

function SHMoveFile(const SourceFile, TargetFile: string): Boolean;
begin
 Result := SHOper(FO_MOVE, SourceFile, TargetFile);
end;

-------- END CODE SNIPPET ------------

And, it works SOMETIMES!?!? ...I get the error:
An error occured in the filesystem (error no 1026),
but ONLY on some files (it seems almost random??).

I don't have any faulty disks/filesystems; it's the
same on all machines i've tried; and I can copy
the file in Windows Explorer, which i assume use the
very same function.

The CopyFile(); and MoveFile(); of Windows unit seems
to work perfect, on ALL files. But I need the l33t
progressbar and so on..

So what am I doing wrong?

I simply call my procedures like:

SHCopyFile('c:\autoexec.bat', 'c:\files\autoexec.bat')

I know the destination directory already exist (i did a ForceDirectories before the call).

What might be wrong? Please help me :]
0
Comment
Question by:blasse
  • 3
  • 2
6 Comments
 
LVL 5

Expert Comment

by:scrapdog
ID: 6328252
I don't know if this is what is causing your problem, but I noticed that you didn't clear the TSHFileOpStruct before you began populating it.  This means that the members of the structure you didn't assign (such as hNameMappings) will probably contain random garbage.

Do this:

FillChar(Info, sizeof(Info), 0);

before you start filling the Info structure.
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6328263
function SHOper(Operator: Cardinal; const SourceFile, TargetFile: String): Boolean;
var
Info: TSHFileOpStruct;

begin
FillChar(Info, sizeof(Info), 0);
with Info do begin
 Wnd := frmSort.Handle;
 wFunc := Operator;
 pFrom := PChar(SourceFile);
 pTo := PChar(TargetFile);
 fFlags := FOF_ALLOWUNDO;
end;

0
 
LVL 1

Accepted Solution

by:
malsoft earned 80 total points
ID: 6329648
Blasse,

The online help forgets to mention one vital piece of information! The filename(s) you pass into the ShellFile Operation are classed as a null separated list, terminating with a null character:

EG

For a single file this means a double null character:

SourceFile := 'Afile.txt'#0#0;

If you want to perform the operation on more than one file at once, this statement would follow this:

SourceFiles:= 'FirstFile.txt'#0'...'#0'LastFile.txt'#0#0

Taking that into account, I'd change your code to the following

-- Begin new code segment --

function SHOper(Operator: Cardinal; const SourceFile, TargetFile: String): Boolean;
var
Info: TSHFileOpStruct;
begin
  // Do a little initialisation first...
  FillChar(Info, sizeof(TSHFileOpStruct), 0);
  SourceFile := SourceFile + ''#0#0;
  TargetFile := TargetFile + ''#0#0;

  with Info do begin
    Wnd := frmSort.Handle;
    wFunc := Operator;
    pFrom := PChar(SourceFile);
    pTo := PChar(TargetFile);
    fFlags := FOF_ALLOWUNDO;
    end;
  Result := (SHFileOperation(Info) = 0);
end;

function SHCopyFile(const SourceFile, TargetFile: string): Boolean;
begin
  Result := SHOper(FO_COPY, SourceFile, TargetFile);
end;

function SHMoveFile(const SourceFile, TargetFile: string): Boolean;
begin
  Result := SHOper(FO_MOVE, SourceFile, TargetFile);
end;

-- End new code segment --

The reasoning behind it actually working sometimes, is that occasionally, the memory area in which the filenames are stored actually contain the proper double-null terminator.

Regards,
Mark Allott
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:blasse
ID: 6329701
Hmm, they really should mention that in the Win32.hlp :]
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6330494
I was wondering about that too...the Win32 Help DOES mention that, but in any Delphi example code (such as in the Delphi 4 Developer's Guide), it ignores this fact.
0
 
LVL 1

Expert Comment

by:malsoft
ID: 6330937
To be honest, it's been a while since I looked at the latest Win32.hlp file for that function. You are correct, it does now state that the list is null-separated! When I first encountered the problem using Delphi 3, the help wasn't much use at all and MSDN didn't have the correct information either (that is now correct as well).
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to convert wav to mp3 in delphi 9 201
Delphi cmd execution 6 60
Delphi Form ownership 4 90
CheckListBox usage 3 59
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question