Inno Setup FileCopy失败

时间:2016-09-16 16:11:07

标签: delphi inno-setup pascal

我正在处理需要在安装之前创建目录备份的安装程序。我实现的方法纯粹是将所有文件从当前目录复制到新目录,然后我可以在旧目录中覆盖文件(我的安装程序)。

但是,我收到一条提示file copy failed,但我无法理解为什么它不起作用。我的错误消息打印出正确的目录\ 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;

2 个答案:

答案 0 :(得分:2)

我怀疑您尝试复制的目录不存在。您需要先使用CreateDirForceDirectories创建目录。文件函数(包括使用这些内部函数的Martin DirectoryCopy函数)要求目录存在或者它们将失败。他们不会自动为您创建路径。遗憾的是,这在任何地方都没有记录(我可以找到,虽然有人可能能够纠正我),因为它也让我感到很沮丧。

Martin DirectoryCopy功能的原始链接可用here

答案 1 :(得分:2)

由于我们没有收到任何可用于调试实际问题的信息,因此我发布了调试文件问题的通用说明。

要找出任何(文件)系统功能失败的原因,请使用GetLastError WinAPI function。您还可以使用SysErrorMessage support function将错误代码转换为邮件。该函数是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);

作为@RobertWigley already posted in his answer,确保目标文件夹存在。如果没有,您将收到错误代码3(系统找不到指定的路径)。

还要确保在NewFile参数(C:\folder\file)中使用目标文件的完整路径。不仅是目标文件夹(C:\folderC:\folder\)的路径。如果仅使用目标文件夹的路径,则会收到错误代码5(访问被拒绝)。

当然这两个代码也可以表明其他问题。