try
CreateProcess(nil, @App[1] , nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, PMSI, PMPI);
except
ErrStr := 'Fault run process: '''+App+'''';
Application.MessageBox(@ErrStr[1],'Failure process', MB_OK+MB_ICONERROR);
end;
разумеется это одно из самых корявых решений, но всё же работает, как вариант сойдет?
Получение списка запущеных приложений
Igor Nikolaev aKa The Sprite предлагает следующий код:
procedure TForm1.Button1Click(Sender: TObject);
VAR
Wnd : hWnd;
buff: ARRAY [0..127] OF Char;
begin
ListBox1.Clear;
Wnd := GetWindow(Handle, gw_HWndFirst);
WHILE Wnd <> 0 DO BEGIN {Hе показываем:}
IF (Wnd <> Application.Handle) AND {-Собственное окно}
IsWindowVisible(Wnd) AND {-Hевидимые окна}
(GetWindow(Wnd, gw_Owner) = 0) AND {-Дочернии окна}
(GetWindowText(Wnd, buff, sizeof(buff)) <> 0)
THEN BEGIN
GetWindowText(Wnd, buff, sizeof(buff));
ListBox1.Items.Add(StrPas(buff));
END;
Wnd := GetWindow(Wnd, gw_hWndNext);
END;
ListBox1.ItemIndex := 0;
end;
Как мне запустить какую-нибудь программу? А как подождать, пока эта программа не отработает? Как выяснить, работает ли программа или уже завершилась? Как принудительно закрыть выполняющуюся программу?
Nomadic рекомендует следующее:
A: WinExec или ShellExecute. У второй больше возможностей.
(SO): CreateProcess в параметре process info возвращает handle запущенного процесса. Вот и делаешь WaitForSingleObject(pi.hProcess, INFINITE);
(AA): (Win16) Delay можно взять из rxLib.
handle := WinExec(…);
if handle >= 32 then
while GetModuleUsage(handle) > 0 do Delay(nn);
else raise …
(AM): Чтобы выяснить, работает ли программа, используйте GetProcessTimes, параметр lpExitTime.
(Win32) Для принудительного завершения процесса — TerminateProcess.
(Win16) (RR): Надо послать программе сообщение WM_QUIT:
Handle := Winexec(App, 0);
PostMessage(Handle, WM_QUIT, 0, 0);
Открытие выбранного файла в работающем приложении
Пангин Дмитрий Викторович прислал письмо следующего содержания:
При программировании MDI-приложений возникает следующая задача: Если пользователь кликнул на файле, тип которого поддерживается создаваемым приложением, то, если приложение уже запущено, не нужно запускать новую копию приложения, а нужно открыть выбранный файл в уже работающем приложении. Я сделал это так (возможно есть более красивое решение):
\\ В файле проекта:
var
i: integer;
hMainForm:hwnd;
copyDataStruct:TCopyDataStruct;
ParamString:string;
WParam,LParam:integer;
begin
\\ ищем главное окно приложения, вместо Caption - nil,
\\ поскольку к заголовку главного окна может добавиться заголовок MDIChild
\\ (нужно позаботиться об уникальности имени класса главной формы)
hMainForm:= FindWindow('TMainForm', nil);
if hMainForm = 0 then begin
Application.Initialize;
Application.CreateForm(TFrmMain, frmMain);
for i:=1 to ParamCount do TMainForm(Application.MainForm).OpenFile(ParamStr(i));
Application.Run;
end
else begin
ParamString:='';
for i:=1 to ParamCount do begin
\\ запихиваем все параметры в одну строку с разделителями ?13
ParamString:=ParamString+ParamStr(i)+ #13;
end;
\\ создаем запись типа TCopyDataStruct
CopyDataStruct.lpData:=PChar(ParamString);