我使用下面的代码通过递归复制文件夹。工作正常,但至少对我来说还是一个问题,因为复制后源文件夹标签也包含在dest文件夹中,我不想要它。此时此刻,会发生什么:
SRC文件夹:
C:\MyTest
-firstfolder
-secondfolder
-- secondfolderFile
DEST文件夹(复制后):
C:\NewTest
-MyTest
-firstfolder
-secondfolder
-- secondfolderFile
然后我需要在dest文件夹中保留它:
C:\NewTest
-firstfolder
-secondfolder
-- secondfolderFile
如何使用以下代码来做到这一点?
program testCopyRecursion;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
ShellAPI,
SysUtils;
function CopyFolder(const SrcFolder, DestFolder: String; iFileOp: Integer;
OverWrite: Boolean; ShowDialog: Boolean): Boolean;
var
MyFOStruct: TSHFileOpStruct;
Src, Dest: String;
ResultVal: Integer;
begin
Result := False;
Src := SrcFolder;
Dest := DestFolder;
if not DirectoryExists(Dest) then
ForceDirectories(Dest);
if (Src = '') or ((iFileOp <> FO_DELETE) and (Dest = '')) or
(CompareText(Src, Dest) = 0) then
Exit;
if Src[Length(Src)] = '\' then
SetLength(Src, Length(Src) - 1);
Src := Src + #0#0;
if (Dest <> '') and (Dest[Length(Dest)] = '\') then
SetLength(Dest, Length(Dest) - 1);
Dest := Dest + #0#0;
FillChar(MyFOStruct, SizeOf(MyFOStruct), 0);
with MyFOStruct do
begin
Wnd := 0;
wFunc := iFileOp;
pFrom := @Src[1];
pTo := @Dest[1];
fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMMKDIR;
if not OverWrite then
fFlags := fFlags or FOF_RENAMEONCOLLISION;
if not ShowDialog then
fFlags := fFlags or FOF_SILENT;
end;
try
MyFOStruct.fAnyOperationsAborted := False;
MyFOStruct.hNameMappings := nil;
ResultVal := ShFileOperation(MyFOStruct);
Result := (ResultVal = 0);
finally
end;
end;
begin
try
CopyFolder('C:\MyTest', 'C:\NewTest', FO_COPY, True, False);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
答案 0 :(得分:5)
您正在将C:\MyTest
文件夹本身复制到C:\NewTest
文件夹中,而不仅仅是复制C:\MyTest
内部的内容。尝试将源路径设置为'C:\MyTest\*'
,而不是仅复制C:\MyTest
内部的内容。
FYI,您不需要调用ForceDirectories()
,因为SHFileOperation()
将创建目标文件夹(如果尚不存在)。 documentation甚至说:
复制和移动操作可以指定不存在的目标目录。在这些情况下,系统会尝试创建它们,并且通常会显示一个对话框,询问用户是否要创建新目录。要取消显示此对话框并以静默方式创建目录,请在
FOF_NOCONFIRMMKDIR
中设置fFlags
标志。
尝试更多类似的方法:
program testCopyRecursion;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows, ShellAPI, SysUtils;
function CopyFolder(const SrcFolder, DestFolder: String;
OverWrite: Boolean; ShowDialog: Boolean): Boolean;
var
MyFOStruct: TSHFileOpStruct;
Src, Dest: String;
begin
Result := False;
if (SrcFolder = '') or (DestFolder = '') or
(CompareText(SrcFolder, DestFolder) = 0) then
Exit;
Src := IncludeTrailingPathDelimiter(SrcFolder) + '*'#0;
Dest := ExcludeTrailingPathDelimiter(DestFolder) + #0;
FillChar(MyFOStruct, SizeOf(MyFOStruct), 0);
with MyFOStruct do
begin
wFunc := FO_COPY;
pFrom := PChar(Src);
pTo := PChar(Dest);
fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMMKDIR;
if not OverWrite then
fFlags := fFlags or FOF_RENAMEONCOLLISION;
if not ShowDialog then
fFlags := fFlags or FOF_SILENT;
end;
Result := (SHFileOperation(MyFOStruct) = 0);
end;
begin
try
CopyFolder('C:\MyTest', 'C:\NewTest', True, False);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.