2013-10-06 66 views
0

此代碼調用Sqlite3.exe來執行數據庫備份,但由於參數中的「>」符號而無法工作。你能告訴我如何解決它嗎?TShellExecuteInfo lpParameters和「>」符號

procedure TfAdmin.DoDBBackup(ADBBackupFile: String); 
var 
    b, p, q: String; 
    ps: TShellExecuteInfo; 
begin 

    b := ExtractFilePath(ParamStr(0)) + 'PPDB.bak'; 
    p := ExtractFilePath(ParamStr(0)) + 'sqlite3.exe'; 
    q := ExtractFilePath(ParamStr(0)) + 'PPDB.db .dump > ' + b; //here lies the problem 

    ShowMessage(p + ' ' + q); 
    fMain.UniConnection1.Close; 
    try 
    // Execute process and wait for it to terminate 
    FillChar(ps, SizeOf(ps), 0); 
    ps.cbSize := SizeOf(ps); 
    ps.Wnd := Handle; 
    ps.lpVerb := Nil; 
    ps.fMask := SEE_MASK_FLAG_NO_UI or SEE_MASK_NOCLOSEPROCESS; 
    ps.lpFile := PChar(p); 
    ps.lpParameters := PChar(q); 
    ps.nShow := SW_SHOWNORMAL; 

    if not ShellExecuteEx(@ps) then 
     RaiseLastOSError; 

    if ps.hProcess <> 0 then 
    begin 
     while WaitForSingleObject(ps.hProcess, 50) = WAIT_TIMEOUT do 
     application.ProcessMessages; 
     CloseHandle(ps.hProcess); 
    end; 
    finally 
    fMain.UniConnection1.Open; 
    end; 
end; 
+1

UniDAC是否包含用於(SQLite)備份的組件?或翻譯SQLite API頭?這種方式可能會起作用,但是,呃,不是很乾淨。那麼['TUniDump'](http://www.devart.com/unidac/docs/index.html?devart_unidac_tunidump.htm)如何呢?這不會與SQLite一起工作嗎? – TLama

+0

還沒有。他們表示,他們將在下一個版本中實施ONLINE BACKUP API(http://forums.devart.com/viewtopic.php?f=28&t=25838&p=88118&hilit=sqlite+backup#p88118)。我不想使用TUniDump,因爲我需要一些性能良好的東西。 –

+0

如果您正在使用SQLite API的Delphi翻譯,我認爲您應該已經將它作爲UniDAC的SQLite實現的一部分,但您可以(具備C語言基礎知識)爲[SQLite Online Backup] ](http://www.sqlite.org/backup.html)。 – TLama

回答

2

>符號指示命令解釋程序(cmd.exe)將輸出從可執行文件重定向到文件。當命令解釋器正在運行節目時,這是有效的。但在這裏,沒有命令解釋器。

有幾種選擇給你。一個非常簡單的方法就是要求指揮官做這項工作。使用cmd.exe作爲您的可執行文件,通過/C參數,然後執行命令行的其餘部分。如果你想成爲一個好公民,那麼使用COMSPEC環境變量的值而不是硬編碼cmd.exe

一個更成熟的解決方案是放棄殼。請直接撥打CreateProcess。這涉及更多一點。您必須通過調用CreateFile來創建文件句柄。將該句柄傳遞給CreateProcess作爲新過程的標準輸出文件句柄。您需要確保在撥打CreateProcess時手柄會繼承。

最後一點是,我真的不喜歡你的等待循環。使用MsgWaitForMultipleObjects阻止排隊的消息到達時,您會更好。

+0

CreateProcess支持執行並等待嗎? –

+0

當然。它返回新創建的進程及其主線程的句柄。然後等待進程句柄發出信號。當你完成它們時,顯然要關閉這兩個手柄。第一步是讓CreateProcess完成工作,而不用擔心標準輸出。然後處理stdout。只要您有能力閱讀此類文檔,CreateProcess的MSDN文檔就可以滿足您的所有需求。很多Delphi程序員在看到C代碼時都很驚訝! –