Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi Inno安装程序文件复制失败_Delphi_Inno Setup_Pascal - Fatal编程技术网

Delphi Inno安装程序文件复制失败

Delphi Inno安装程序文件复制失败,delphi,inno-setup,pascal,Delphi,Inno Setup,Pascal,我正在安装一个需要在安装之前创建目录备份的安装程序。我实现的方法纯粹是将当前目录中的所有文件复制到一个新目录,然后我可以自由地覆盖旧目录中的文件(我的安装程序) 但是,我收到一条提示,指示文件复制失败,但我无法理解为什么它不起作用。我的错误消息打印了正确的目录\文件名,我可以验证它们是否存在,是否在任何外部程序中打开 以下是代码,摘自(并稍作修改): 函数DirectoryCopy(SourcePath,DestPath:string):布尔值; 变量 FindRec:TFindRec; Sou

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

但是,我收到一条提示,指示
文件复制失败
,但我无法理解为什么它不起作用。我的错误消息打印了正确的目录\文件名,我可以验证它们是否存在,是否在任何外部程序中打开

以下是代码,摘自(并稍作修改):

函数DirectoryCopy(SourcePath,DestPath:string):布尔值;
变量
FindRec:TFindRec;
SourceFilePath:string;
DestFilePath:string;
开始
如果FindFirst(SourcePath+'\*',FindRec),则开始
尝试
重复
如果(FindRec.Name'.'和(FindRec.Name'.'),则开始
SourceFilePath:=SourcePath+'\'+FindRec.Name;
DestFilePath:=DestPath+'\'+FindRec.Name;
如果FindRec.Attributes和FILE_ATTRIBUTE_DIRECTORY=0,则开始
如果是FileCopy(SourceFilePath、DestFilePath、False),则开始
结果:=真;
MsgBox('Copy Worked!',MB信息,MB_OK);
结束,否则开始
结果:=假;
MsgBox('Copy Failed!'+SourceFilePath,mbInformation,MB_OK);
结束;
结束,否则开始
如果是CreateDir(DestFilePath),则开始
结果:=真;
MsgBox('Created Dir!',mbInformation,MB_OK);
DirectoryCopy(SourceFilePath、DestFilePath);
结束,否则开始
结果:=假;
MsgBox('创建目录失败!',MB信息,MB_确定);
结束;
结束;
结束;
直到没有FindNext(FindRec);
最后
FindClose(FindRec);
结束;
结束,否则开始
结果:=假;
MsgBox('未能列出!',MB信息,MB_确定);
结束;
结束;

我怀疑您试图复制到的目录不存在。您需要首先使用
CreateDir
ForceDirectories
创建目录。文件函数(包括Martin的
DirectoryCopy
函数,它使用这些内部函数)要求目录存在,否则它们将失败。它们不会自动为您创建路径。遗憾的是,这一点在任何地方都没有记录(我可以找到,尽管有人可能会纠正我的错误),因为它也让我感到困惑了一段时间


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

由于我们没有收到任何可用于调试实际问题的信息,我将发布有关调试文件问题的一般说明

要找出任何(文件)系统功能失败的原因,请使用。还可以使用将错误代码转换为消息。该函数是的包装器

函数GetLastError:Cardinal; 外部的GetLastError@kernel32.dllstdcall'; 函数FileCopyLogged(ExistingFile,NewFile:String;FailIfExists:Boolean):布尔; 变量 错误:基数; 开始 结果:=FileCopy(ExistingFile、NewFile、FailIfExists); 如果没有结果的话 开始 错误:=GetLastError; 日志( 格式( '将“%s”复制到“%s”失败,代码为%d(0x%x)-%s'[ 现有文件、新文件、错误、错误、系统错误消息(错误)]); 结束 其他的 开始 日志(格式(将“%s”复制到“%s”成功,[ExistingFile,NewFile]); 结束; 结束;
正确调用
FileCopy
(或
FileCopyLogged
)如下:

FileCopyLogged(
ExpandConstant(“{app}\MyProg.exe”),
ExpandConstant(“{app}\archive\MyProg.exe”),
假);

作为,请确保目标文件夹存在。如果没有,您将得到错误代码3(系统找不到指定的路径)

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


当然,这两个代码也可能表明存在其他问题。

请举例说明复制失败的
SourceFilePath
DestFilePath
的实际值。当
FileCopy
失败时,
DLLGetLastError
返回什么?您有DestPath的写入权限吗?DestPath确实有效吗?可能有点离题,但要创建文件的备份副本,您将覆盖这些文件,最好在复制新文件之前将这些旧文件移动/重命名为新位置/名称。通过这种方式,您可以避免实际复制旧文件中的数据,这可能需要一些时间,并且还可以避免在复制过程中发生数据损坏的可能性,因为通过移动/重命名,只会修改文件表中的数据项,以表示现有文件的新位置/名称,这要快得多。。。。。。这种方法的缺点是,如果您不替换所有文件,并且某些文件必须保持完整,则无法对该目录中的每个文件执行此操作。但是我也不明白,如果不是所有的文件都被替换成新的,为什么你要复制所有的文件。你可以考虑的另一种方法是将那些旧文件归档到一个zip存档中。这样可以节省一些硬盘空间。如果您的程序会不必要地占用空间,特别是使用SSD驱动器的用户,那么没有多少用户会很高兴。。。
FileCopy
不创建目标文件夹是很自然的。没有任何迹象表明它确实如此。这是一个简单的函数,只有一个目的。你不能指望它做更多的事情。无需记录+1.无论如何,Cr
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;