2013-10-06 5 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

아직 등급이 아닙니다. 그들은 다음 버전 (http://forums.devart.com/viewtopic.php?f=28&t=25838&p=88118&hilit=sqlite+backup#p88118)에서 ONLINE BACKUP API를 구현할 것이라고 말합니다. 좋은 성능을 필요로하기 때문에 TUniDump를 사용하고 싶지 않습니다. –

+0

Delphi에서 SQLite API를 번역 한 적이 있다면, UniDAC의 SQLite 구현의 일부로 이미 가지고 있다고 생각할 수 있습니다. C 언어에 대한 기본적인 지식으로 [SQLite 온라인 백업] 코드를 작성할 수 있습니다. ] (http://www.sqlite.org/backup.html)을 방문하십시오. – TLama

답변

2

> 기호는 명령 인터프리터 (cmd.exe를)이 파일에 실행 파일의 출력을 리디렉션하도록 지시합니다. 명령 해석기가 프로그램을 실행할 때 작동합니다. 그러나 여기에는 명령 해석기가 없습니다.

몇 가지 옵션이 있습니다. 아주 간단한 방법은 명령 해석자에게 작업을 요청하는 것입니다. 실행 파일로 cmd.exe을 사용하고 /C 인수를 전달한 다음 나머지 명령 행을 전달하십시오. 좋은 시민이 되려면 cmd.exe이 아닌 COMSPEC 환경 변수의 값을 사용하십시오.

더 큰 솔루션은 쉘을 버리는 것입니다. 대신 CreateProcess으로 직접 전화하십시오. 이것은 좀 더 복잡합니다. CreateFile을 호출하여 파일 핸들을 만들어야합니다. 해당 핸들을 CreateProcess으로 새 프로세스의 표준 출력 파일 핸들로 전달하십시오. CreateProcess에 전화 할 때 핸들이 상속되는지 확인해야합니다.

마지막으로 요점은 내가 대기 루프가 마음에 들지 않는다는 것입니다. 대기중인 메시지가 도착할 때까지 차단하려면 MsgWaitForMultipleObjects을 사용하는 것이 훨씬 낫습니다.

+0

CreateProcess 지원이 실행되고 대기합니까? –

+0

물론. 새로 생성 된 프로세스와 주 스레드에 대한 핸들을 반환합니다. 그런 다음 프로세스 핸들이 신호를받을 때까지 기다립니다. 그리고 당신이 그들과 함께 완료되면 분명히 두 핸들을 닫습니다. 1 단계는 CreateProcess가 stdout에 대해 걱정하지 않고 작업을 수행하는 것입니다. 그런 다음 표준 처리에 압정을가하십시오. CreateProcess 용 MSDN 문서에는 해당 문서를 읽는 데 유능한 한 필요한 모든 것이 있습니다. 많은 델파이 프로그래머들이 C 코드를보고 놀랐습니다 !! –