在另一个进程中打开文件时,Inno Setup LoadStringFromFile 失败
Inno Setup LoadStringFromFile fails when file is open in another process
为了检查数据库(SQL Anywhere)何时启动并准备好接收请求,我将数据库消息 window 输出到日志(文本)文件,然后尝试使用 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;
有什么方法可以读取正在使用的文件或其他方法吗?
使用 TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone)
.
在 Inno Setup 的 Unicode 版本(Inno Setup 6 的唯一版本)中,由于 class.
的界面不佳,它的使用很棘手
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 posted in .
生成数据库服务器时,使用专为此目的设计的 dbspawn
实用程序。您生成 dbspawn
以及您想要 运行 的 dbeng/dbsrv 命令,它会为您启动服务器。 dbspawn 实用程序不会 return 直到数据库服务器启动,运行 并且准备好接受请求,因此不需要猜测,也不需要读取控制台日志文件。
我不知道 SQL 是什么版本 运行ning,但这是 documentation for v17。其他版本应该都一样。
为了检查数据库(SQL Anywhere)何时启动并准备好接收请求,我将数据库消息 window 输出到日志(文本)文件,然后尝试使用 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;
有什么方法可以读取正在使用的文件或其他方法吗?
使用 TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone)
.
在 Inno Setup 的 Unicode 版本(Inno Setup 6 的唯一版本)中,由于 class.
的界面不佳,它的使用很棘手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 posted in
生成数据库服务器时,使用专为此目的设计的 dbspawn
实用程序。您生成 dbspawn
以及您想要 运行 的 dbeng/dbsrv 命令,它会为您启动服务器。 dbspawn 实用程序不会 return 直到数据库服务器启动,运行 并且准备好接受请求,因此不需要猜测,也不需要读取控制台日志文件。
我不知道 SQL 是什么版本 运行ning,但这是 documentation for v17。其他版本应该都一样。