此代码调用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;
答案 0 :(得分:2)
>
符号指示命令解释程序(cmd.exe)将可执行文件的输出重定向到文件。这在命令解释器运行节目时有效。但在这里,没有命令解释器。
有几种选择。一个非常简单的方法是让命令解释器完成工作。使用cmd.exe
作为可执行文件,传递/C
参数,然后传递命令行的其余部分。如果您想成为一个好公民,那么请使用COMSPEC
环境变量的值而不是硬编码cmd.exe
。
更成熟的解决方案是放弃shell。而是直接致电CreateProcess
。这有点多了。您必须通过调用CreateFile
来创建文件句柄。将该句柄传递给CreateProcess
作为新进程的标准输出文件句柄。调用CreateProcess
时,您需要确保继承句柄。
要做的最后一点是我真的不喜欢你的等待循环。使用MsgWaitForMultipleObjects
阻止直到排队的邮件到达时,你会好得多。