她的片段来自我用于类似目的的单元。这些年来,我在网上的某个地方发现了这些功能,所以我不相信也不做任何承诺。
我个人使用 WaitExec() 函数在 Acrobat 中启动 pdf(从数据库中检索)进行编辑,然后在完成后将其重新保存到我们的数据库中。
我在其他时候也使用过另外两个函数,所以我知道它们都在某种程度上工作,但我认为 WaitExec() 在交互模式下效果最好,而 Launch() 在线程或非交互模式下效果更好.
IsFileInUse 函数可以告诉您您创建的文件是否正在被任何其他进程使用,并且可能也是一个可行的选项。
uses SysUtils, Windows, ShellAPI, Forms, Registry, Classes, Messages, Printers,
PSAPI, TlHelp32, SHFolder;
function IsFileInUse(fName: string): boolean;
var
HFileRes: HFILE;
begin
Result := False;
if not FileExists(fName) then
Exit;
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,
0 {this is the trick!}, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;
function Launch(sCommandLine: string; bWait: Boolean; AppHandle: HWND): Boolean;
var
SEI: TShellExecuteInfo;
Mask: Longint;
begin
Mask := SEE_MASK_NOCLOSEPROCESS;
FillChar(SEI, Sizeof(SEI), #0);
SEI.cbsize := Sizeof(SEI);
SEI.wnd := AppHandle;
SEI.fmask := Mask;
//if FExeStyleString<>'' then SEI.LPVERB:=pchar(FExeStyleString);
SEI.LPFile := pchar(sCommandline);
//SEI.LPParameters := pchar(FExeParameters);
//SEI.LPDirectory := pchar(FExepath);
SEI.nshow := SW_SHOWNORMAL; // SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED
ShellexecuteEx(@SEI);
if bWait then
WaitforSingleObject(SEI.hProcess, INFINITE);
Result := True;
end;
function WaitExec(const CmdLine:AnsiString;const DisplayMode:Integer):Integer;
{Execute an app, wait for it to terminate then return exit code. Returns -1
if execution fails. DisplayMode is usually either sw_ShowNormal or sw_Hide.}
var
S:TStartupInfo;
P:TProcessInformation;
M:TMsg;
R:DWord;
begin
FillChar(P,SizeOf(P),#0);
FillChar(S,Sizeof(S),#0);
S.cb := Sizeof(S);
S.dwFlags := STARTF_USESHOWWINDOW;
S.wShowWindow := DisplayMode;
if not CreateProcess(nil,
PChar(CmdLine), { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
False, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
S, { pointer to STARTUPINFO }
P) { pointer to PROCESS_INF }
then begin
ShowMessage('Create Process failed. Save this message for IT: ' + CmdLine);
Result:=-1
end
else begin
// WaitforSingleObject(P.hProcess,INFINITE);
// The following replacement better satisfies DDE requirements
repeat
R := MsgWaitForMultipleObjects(1, // One event to wait for
P.hProcess, // The array of events
FALSE, // Wait for 1 event
INFINITE, // Timeout value
QS_ALLINPUT); // Any message wakes up
if R>WAIT_OBJECT_0 then begin
M.Message := 0;
while PeekMessage(M,0,0,0,PM_REMOVE) do begin
TranslateMessage(M);
DispatchMessage(M);
end
end;
until R=WAIT_OBJECT_0;
// put value into Result.... non zero = success
GetExitCodeProcess(P.hProcess,DWord(Result));
CloseHandle(P.hProcess);
CloseHandle(P.hThread);
P.hProcess:=0;
P.hThread:=0;
end;
end;