2016-12-09 14 views
2

檢查時看到一個數據庫(SQL Anywhere的)被解僱了,並準備接收到一個日誌請求我輸出數據庫信息窗口(文本)文件,然後試圖打開LoadStringFromFile失敗請使用LoadStringFromFile來閱讀本文,然後使用Pos來搜索特定的文本。問題是這個失敗(我假設),因爲該文件正在使用中。Inno Setup的時候文件是在另一個進程

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; 

有沒有什麼方法可以讀取正在使用的文件或其他方式來執行此操作?

回答

1

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

在創新安裝的Unicode版本,它的使用是非常棘手,由於類的壞接口。

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

+1

我接受這個作爲回答,因爲它直接回答我提出的問題。然而,在這種情況下,Graeme Perrow的答案實際上是一種更加優雅和簡單的方式,用於告知何時啓動數據庫並接受SQL Anywhere中的請求。 –

+1

我upvoted其他答案來彌補。謝謝。 –

2

當產卵的數據庫服務器,使用dbspawn工具,它是專爲這一目的。您生成dbspawn以及要運行的dbeng/dbsrv命令,並且會爲您啓動服務器。在數據庫服務器啓動,運行並準備好接受請求之前,dbspawn實用程序不會返回,因此不需要猜測,也無需讀取控制檯日誌文件。

我不知道任何你正在運行的SQL版本,但這裏是documentation for v17。它應該在任何其他版本中都是一樣的。

+2

我接受了Martin Prikryl的答案,因爲它直接解決了我詢問的編碼問題,並且與其他尋找此問題答案的人最相關。但是,我已經使用您的答案來解決我的問題。這正是我在這個特殊情況下所需要的。我的解決方案是一個解決方案,我不知道這個方便的小實用程序。謝謝。 Upvoted。 –