【问题标题】:Inno Setup LoadStringFromFile fails when file is open in another process当文件在另一个进程中打开时,Inno Setup LoadStringFromFile 失败
【发布时间】:2016-12-09 10:47:28
【问题描述】:

要检查数据库 (SQL Anywhere) 何时启动并准备好接收请求,我将数据库消息窗口输出到日志(文本)文件,然后尝试使用 LoadStringFromFile 读取它,然后我使用Pos 搜索特定文本。问题是这会失败(我假设),因为文件正在使用中。

Exec(strInstallPath + '\Bin32\dbeng17.exe', '-n ' + strEngineName + ' "' + strInstallPath + '\Database\Olympus.db" -n ' + strDatabaseName + ' -gdall -xtcpip -ti0 -c25p -ot "' + strTempPath + '\dbeng.log"', '', SW_HIDE,
  ewNoWait, intResultCode);
if not LoadStringFromFile(strTempPath + '\dbeng.log', astrDatabaseEngineLog) then
  begin
    Log('Loading string from file failed.');
  end;

我也尝试使用FileCopy 复制日志文件并尝试从文件副本中读取,但FileCopy 也失败了。

if not FileCopy(strTempPath + '\dbeng.log', strTempPath + '\dbengcopy.log', False) then
  begin
    Log('File copy failed.');
  end;

有什么方法可以从正在使用的文件中读取数据或其他方法吗?

【问题讨论】:

    标签: inno-setup sqlanywhere pascalscript


    【解决方案1】:

    生成数据库服务器时,请使用专为此目的设计的dbspawn 实用程序。您生成 dbspawn 以及要运行的 dbeng/dbsrv 命令,它会为您启动服务器。在数据库服务器启动、运行并准备好接受请求之前,dbspawn 实用程序不会返回,因此无需猜测,也无需读取控制台日志文件。

    我不知道您运行的是哪个版本的 SQL Anywhere,但这里是 documentation for v17。在任何其他版本中都应该是相同的。

    【讨论】:

    • 我已经接受了 Martin Prikryl 的回答,因为它直接解决了我提出的编码问题,并且对于寻找这个问题的答案的其他人来说是最相关的。但是,我实际上已将您的答案用于我的解决方案。这正是我在这种特殊情况下所需要的。我的解决方案是在不知道这个方便的小实用程序的情况下提出的一种解决方法。谢谢。赞成。
    【解决方案2】:

    使用TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone)

    在 Inno Setup 的 Unicode 版本(Inno Setup 6 的唯一版本)中,由于类的接口不好,它的使用很棘手。

    function BufferToAnsi(const Buffer: string): AnsiString;
    var
      W: Word;
      I: Integer;
    begin
      SetLength(Result, Length(Buffer) * 2);
      for I := 1 to Length(Buffer) do
      begin
        W := Ord(Buffer[I]);
        Result[(I * 2)] := Chr(W shr 8); { high byte }
        Result[(I * 2) - 1] := Chr(Byte(W)); { low byte }
      end;
    end;
    
    function LoadStringFromLockedFile(const FileName: string; var S: AnsiString): Boolean;
    var
      Buffer: string;
      Stream: TFileStream;
    begin
      Result := True;
      try
        Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
        try
          SetLength(Buffer, Stream.Size div 2);
          Stream.ReadBuffer(Buffer, Stream.Size);
          S := BufferToAnsi(Buffer);
        finally
          Stream.Free;
        end;
      except
        Result := False;
      end;
    end;
    

    代码基于TLama's code 发布在Read bytes from file at desired position with Inno Setup

    【讨论】:

    • 我接受这个作为答案,因为它直接回答了我提出的问题。然而,在这种情况下,Graeme Perrow 的回答实际上是一种更加优雅和简单的方式来判断数据库何时启动并在 SQL Anywhere 中接受请求。
    猜你喜欢
    • 1970-01-01
    • 2020-12-11
    • 2021-07-17
    • 2011-01-29
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多