0

此代码调用 Sqlite3.exe 进行数据库备份,但由于参数中的“>”符号而无法正常工作。你能告诉我如何解决吗?

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;
4

1 回答 1

2

>符号指示命令解释器 (cmd.exe) 将输出从可执行文件重定向到文件。这在命令解释器运行节目时有效。但是在这里,没有命令解释器。

有几个选项供您选择。一个非常简单的方法是让命令解释器完成这项工作。cmd.exe用作您的可执行文件,传递参数/C,然后传递命令行的其余部分。如果你想成为一个好公民,那么使用COMSPEC环境变量的值而不是硬编码cmd.exe

一个更成熟的解决方案是放弃外壳。而是CreateProcess直接调用。这涉及更多一点。您必须通过调用来创建文件句柄CreateFileCreateProcess将该句柄作为新进程的标准输出文件句柄传递。您需要确保在调用CreateProcess.

最后一点是我真的不喜欢你的等待循环。MsgWaitForMultipleObjects在排队的消息到达之前,您最好使用阻塞。

于 2013-10-06T15:39:10.747 回答