所以我尝试使用delphi和ShellExecuteEx进行存档我的代码是:
Result := False;
DecodeDate(now,y,m,d);
NumeFisier := dir+'\Export_'+IntToStr(y)+'.'+IntToStr(m)+'.'+IntToStr(d)+'.zip';
FillChar(exInfo, SizeOf(exInfo), 0);
with exInfo do
begin
cbSize := SizeOf(exInfo);
fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
Wnd := GetActiveWindow();
exInfo.lpVerb := nil;
exInfo.lpFile := PAnsiChar('C:\Windows\System32\cmd.exe');
exInfo.lpParameters := PAnsiChar('C:\Program Files\7-Zip\7z.exe ' +'a ' + NumeFisier + ' ' + dir);
nShow := SW_SHOWNORMAL;
end;
if ShellExecuteEx(@exInfo) then
Ph := exInfo.hProcess
else
begin
ShowMessage(SysErrorMessage(GetLastError));
Result := true;
exit;
end;
while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
Application.ProcessMessages;
CloseHandle(Ph);
Result := true;
由于某种原因,这只会打开命令提示符,并且不会执行存档。我怎么能让它执行7z.exe文件。
我尝试使用ShellExecute并且它运行良好,但我必须检查然后该过程已完成,所以我坚持使用ShellExecuteEx
答案 0 :(得分:3)
无需涉及cmd.exe
。那是命令解释器。您想要执行不同的可执行文件,因此请直接执行。
您不想使用ShellExecuteEx
,因为它比您需要的更具普遍性。 ShellExecuteEx
所做的只是调用CreateProcess
。你应该直接这样做,避免中间人。更重要的是,调用CreateProcess
可以让您轻松隐藏控制台窗口。通过CREATE_NO_WINDOW
来实现这一目标。
最后,还有比代码更好的等待方式。使用MsgWaitForMultipleObjects
可以避免轮询。将此代码放入线程可以避免调用Application.ProcessMessages
。
procedure WaitUntilSignaled(Handle: THandle; ProcessMessages: Boolean);
var
retval: DWORD;
begin
if ProcessMessages then begin
Application.ProcessMessages;//in case there are messages already in the queue
while True do begin
retval := MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLEVENTS);
case retval of
WAIT_OBJECT_0,WAIT_ABANDONED_0:
break;
WAIT_OBJECT_0+1:
Application.ProcessMessages;
WAIT_FAILED:
RaiseLastOSError;
end;
end;
end else begin
Win32Check(WaitForSingleObject(Handle, INFINITE)<>WAIT_FAILED);
end;
end;
procedure ExecuteProcess(
const ExecutablePath: string;
const Arguments: string;
const CurrentDirectory: string;
const Wait: Boolean;
const CreationFlags: DWORD
);
var
si: TStartupInfo;
pi: TProcessInformation;
MyCurrentDirectory: PChar;
begin
ZeroMemory(@si, SizeOf(si));
si.cb := SizeOf(si);
if CurrentDirectory <> '' then begin
MyCurrentDirectory := PChar(CurrentDirectory);
end else begin
MyCurrentDirectory := nil;
end;
Win32Check(CreateProcess(
nil,
PChar('"' + ExecutablePath + '" ' + Arguments),
nil,
nil,
False,
CreationFlags,
nil,
MyCurrentDirectory,
si,
pi
));
try
if Wait then begin
WaitUntilSignaled(pi.hProcess, True);
end;
finally
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end;
end;