Inno Setup FileCopy 失败
Inno Setup FileCopy failing
我正在开发一个需要在安装前创建目录备份的安装程序。我实现的方法纯粹是将当前目录的所有文件复制到新目录,然后我可以随意覆盖旧目录中的文件(我的安装程序)。
然而,我收到提示file copy failed
,但我不明白为什么它不起作用。我的错误消息打印出正确的 directory\filename,我可以验证它们是否存在并且未在任何外部程序中打开。
下面是代码,取自(并稍作修改):http://blogs.candoerz.com/question/139833/inno-setup-copy-folder-subfolders-and-files-recursively-in-code-section.aspx
function DirectoryCopy(SourcePath, DestPath: string): boolean;
var
FindRec: TFindRec;
SourceFilePath: string;
DestFilePath: string;
begin
if FindFirst(SourcePath + '\*', FindRec) then begin
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin
SourceFilePath := SourcePath + '\' + FindRec.Name;
DestFilePath := DestPath + '\' + FindRec.Name;
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin
if FileCopy(SourceFilePath, DestFilePath, False) then begin
Result := True;
MsgBox('Copy Worked!', mbInformation, MB_OK);
end else begin
Result := False;
MsgBox('Copy Failed!'+SourceFilePath, mbInformation, MB_OK);
end;
end else begin
if CreateDir(DestFilePath) then begin
Result := True;
MsgBox('Created Dir!', mbInformation, MB_OK);
DirectoryCopy(SourceFilePath, DestFilePath);
end else begin
Result := False;
MsgBox('Failed to create Dir!', mbInformation, MB_OK);
end;
end;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end else begin
Result := False;
MsgBox('Failed to List!', mbInformation, MB_OK);
end;
end;
我怀疑您要复制到的目录不存在。您需要先使用 CreateDir
或 ForceDirectories
创建目录。文件函数(包括 Martin 的 DirectoryCopy
函数,它使用这些内部函数)要求目录存在,否则它们将失败。他们不会自动为您创建路径。遗憾的是,这在任何地方都没有记录(我能找到,尽管有人可能会纠正我)因为它也让我困惑了一段时间。
原来link到Martin的DirectoryCopy
函数可用。
由于我们没有收到任何可用于调试您的实际问题的信息,我发布了用于调试文件问题的通用说明。
要找出任何(文件)系统功能失败的原因,请使用 GetLastError
WinAPI function. You can also use the SysErrorMessage
support function to convert an error code to a message. The function is a wrapper for the FormatMessage
WinAPI function。
function GetLastError: Cardinal;
external 'GetLastError@kernel32.dll stdcall';
function FileCopyLogged(
ExistingFile, NewFile: String; FailIfExists: Boolean): Boolean;
var
Error: Cardinal;
begin
Result := FileCopy(ExistingFile, NewFile, FailIfExists);
if not Result then
begin
Error := GetLastError;
Log(
Format(
'Copying "%s" to "%s" failed with code %d (0x%x) - %s', [
ExistingFile, NewFile, Error, Error, SysErrorMessage(Error)]));
end
else
begin
Log(Format('Copying "%s" to "%s" succeeded', [ExistingFile, NewFile]));
end;
end;
对 FileCopy
(或 FileCopyLogged
)的正确调用如下:
FileCopyLogged(
ExpandConstant('{app}\MyProg.exe'),
ExpandConstant('{app}\archive\MyProg.exe'),
False);
如,确保目标文件夹存在。如果没有,您将收到错误代码 3 (系统找不到指定的路径).
还要确保在 NewFile
参数 (C:\folder\file
) 中使用目标文件的完整路径。不仅仅是目标文件夹的路径(C:\folder
或 C:\folder\
)。如果您只使用目标文件夹的路径,您将收到错误代码 5 (访问被拒绝).
当然这两个代码也可以指示其他问题。
我正在开发一个需要在安装前创建目录备份的安装程序。我实现的方法纯粹是将当前目录的所有文件复制到新目录,然后我可以随意覆盖旧目录中的文件(我的安装程序)。
然而,我收到提示file copy failed
,但我不明白为什么它不起作用。我的错误消息打印出正确的 directory\filename,我可以验证它们是否存在并且未在任何外部程序中打开。
下面是代码,取自(并稍作修改):http://blogs.candoerz.com/question/139833/inno-setup-copy-folder-subfolders-and-files-recursively-in-code-section.aspx
function DirectoryCopy(SourcePath, DestPath: string): boolean;
var
FindRec: TFindRec;
SourceFilePath: string;
DestFilePath: string;
begin
if FindFirst(SourcePath + '\*', FindRec) then begin
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin
SourceFilePath := SourcePath + '\' + FindRec.Name;
DestFilePath := DestPath + '\' + FindRec.Name;
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin
if FileCopy(SourceFilePath, DestFilePath, False) then begin
Result := True;
MsgBox('Copy Worked!', mbInformation, MB_OK);
end else begin
Result := False;
MsgBox('Copy Failed!'+SourceFilePath, mbInformation, MB_OK);
end;
end else begin
if CreateDir(DestFilePath) then begin
Result := True;
MsgBox('Created Dir!', mbInformation, MB_OK);
DirectoryCopy(SourceFilePath, DestFilePath);
end else begin
Result := False;
MsgBox('Failed to create Dir!', mbInformation, MB_OK);
end;
end;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end else begin
Result := False;
MsgBox('Failed to List!', mbInformation, MB_OK);
end;
end;
我怀疑您要复制到的目录不存在。您需要先使用 CreateDir
或 ForceDirectories
创建目录。文件函数(包括 Martin 的 DirectoryCopy
函数,它使用这些内部函数)要求目录存在,否则它们将失败。他们不会自动为您创建路径。遗憾的是,这在任何地方都没有记录(我能找到,尽管有人可能会纠正我)因为它也让我困惑了一段时间。
原来link到Martin的DirectoryCopy
函数可用
由于我们没有收到任何可用于调试您的实际问题的信息,我发布了用于调试文件问题的通用说明。
要找出任何(文件)系统功能失败的原因,请使用 GetLastError
WinAPI function. You can also use the SysErrorMessage
support function to convert an error code to a message. The function is a wrapper for the FormatMessage
WinAPI function。
function GetLastError: Cardinal;
external 'GetLastError@kernel32.dll stdcall';
function FileCopyLogged(
ExistingFile, NewFile: String; FailIfExists: Boolean): Boolean;
var
Error: Cardinal;
begin
Result := FileCopy(ExistingFile, NewFile, FailIfExists);
if not Result then
begin
Error := GetLastError;
Log(
Format(
'Copying "%s" to "%s" failed with code %d (0x%x) - %s', [
ExistingFile, NewFile, Error, Error, SysErrorMessage(Error)]));
end
else
begin
Log(Format('Copying "%s" to "%s" succeeded', [ExistingFile, NewFile]));
end;
end;
对 FileCopy
(或 FileCopyLogged
)的正确调用如下:
FileCopyLogged(
ExpandConstant('{app}\MyProg.exe'),
ExpandConstant('{app}\archive\MyProg.exe'),
False);
如
还要确保在 NewFile
参数 (C:\folder\file
) 中使用目标文件的完整路径。不仅仅是目标文件夹的路径(C:\folder
或 C:\folder\
)。如果您只使用目标文件夹的路径,您将收到错误代码 5 (访问被拒绝).
当然这两个代码也可以指示其他问题。