Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.20;
Скачать: CL | DM;

Вниз

Открыть и закрыть чужую программу.   Найти похожие ветки 

 
STK ©   (2005-01-03 19:44) [0]

С наступившем Всех.
Банальный вопрос конечно, но мне надо запустить несколько чужих программ зная их путь, и через некоторое время их закрыть(по одному открыть и поодному закрыть). При этом обе программы могут быть свёрнуты развернуты, без разницы. Поиск по имени окна не подойдёт у всех запускаемых программ разные Caption.
<br>Я многое испробовал. но чё то ни черта не работает.  <br> Заранее спасибо.


 
Davinchi ©   (2005-01-03 20:34) [1]

Пример всегда лучше слов:

function ExecuteFile(const FileName, Params, DefaultDir: String;
ShowCmd: Integer): THandle;
var
 zFileName, zParams, zDir: array[0..79] of Char;

begin
Result := ShellExecute(Application.MainForm.Handle, nil,
StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),
StrPCopy(zDir, DefaultDir), ShowCmd);
end;  


Пример вызова:


   executeFile("maker.exe","text_file","c:\maker",
SW_SHOWNORMAL);


А завершить процесс:

TerminateProcess(hProcess, 0);
CloseHandle(hProcess);


 
STK ©   (2005-01-04 00:02) [2]

Davinchi.
Спасибо за столь быстрый ответ пойду попробую. Но чё то весь этот код мне до более знаком. Но если получится напишу.
С новым годом всех кто в такие дни не покидает ФОРУМ.


 
STK ©   (2005-01-04 00:50) [3]

Davinchi.
Прикинь не хрена она не работает, т.e. запускает конечно (это и уменя получилось), но вот закрывать она не хочет.
Думается мне что не определяется hProcess:
когда закрывем чужую прогу:
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);

Пробовал и Result использовать но не чего не дало.
Может кто чего подскажет.
Если что то запускается Project Flash (Масяня *.exe).
Заранее ЕЩЁ раз сабасибо.


 
GanibalLector ©   (2005-01-04 01:18) [4]


var
Rlst: LongBool;
StartUpInfo: TStartUpInfo;
ProcessInfo: TProcessInformation;
Error: integer;
ExitCode: Cardinal;
begin
FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
with StartUpInfo do
begin
cb := SizeOf(TStartUpInfo);
dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
wShowWindow := SW_SHOWNORMAL;
end;
Rlst := CreateProcess("E:\Windows\System32\calc.exe", nil, nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);
if Rlst then
with ProcessInfo do begin
WaitForInputIdle(hProcess, INFINITE); // &#230;&#228;&#229;&#236; &#231;&#224;&#226;&#229;&#240;&#248;&#229;&#237;&#232;&#255; &#232;&#237;&#232;&#246;&#232;&#224;&#235;&#232;&#231;&#224;&#246;&#232;&#232;
Sleep(2000);
TerminateProcess(hProcess, NO_ERROR);
CloseHandle(hThread); // &#231;&#224;&#234;&#240;&#251;&#226;&#224;&#229;&#236; &#228;&#229;&#241;&#234;&#240;&#232;&#239;&#242;&#238;&#240; &#239;&#240;&#238;&#246;&#229;&#241;&#241;&#224;
CloseHandle(hProcess); // &#231;&#224;&#234;&#240;&#251;&#226;&#224;&#229;&#236; &#228;&#229;&#241;&#234;&#240;&#232;&#239;&#242;&#238;&#240; &#239;&#238;&#242;&#238;&#234;&#224;
end
else Error := GetLastError;


 
GuAV ©   (2005-01-04 01:55) [5]

Блин, что вы так грубо... TerminateProcess...
Не лучше ли найти окно верхнего уровня, видное на taskbar и попытаться закрыть его WM_SYSCOMMAND, SC_CLOSE ?


 
GuAV ©   (2005-01-04 02:13) [6]

function EnumThreadWndProc(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
var exstyle: DWORD;
begin
 if IsWindowVisible(hWnd) then
   begin
      exstyle := GetWindowLong(hWnd, GWL_EXSTYLE);
      if ((exstyle and WS_EX_APPWINDOW <> 0) or
        (exstyle and WS_EX_TOOLWINDOW = 0)) and
       (GetWindowLong(hWnd, GWL_HWNDPARENT) = 0) then
        begin
          PHandle(lParam)^ := hWnd;
          Result := False;
          Exit;
        end;
   end;
 Result := True;
end;

procedure RunAndCloseCalc;
var
 StartupInfo: TStartupInfo;
 ProcessInfo: TProcessInformation;
 hwndMain: HWND;
begin
 FillChar(StartupInfo, SizeOf(StartupInfo), 0);
 StartupInfo.cb := SizeOf(StartupInfo);
 if not CreateProcess(nil, "calc.exe", nil, nil, False, 0,
   nil, nil, StartUpInfo, ProcessInfo) then RaiseLastOSError;
 with ProcessInfo do
 begin
   WaitForInputIdle(hProcess, INFINITE);
   Sleep(2000);
   EnumThreadWindows(dwThreadId, @EnumThreadWndProc,
     LPARAM(@hwndMain));
   if hwndMain <> 0 then
     SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
 end;
end;


 
GuAV ©   (2005-01-04 02:22) [7]

GuAV ©   (04.01.05 2:13) [6]
Пора закрывать хендлы CloseHandle(hThread); CloseHandle(hProcess); и идти спать.


 
STK ©   (2005-01-04 23:18) [8]

>> GanibalLector-у
Спасибо большое реально работает.
Спасибо всем кто отвечал.


 
GuAV ©   (2005-01-05 00:14) [9]

...а всё таки убивать процесс нехорошо...это только "at last resort"..


 
STK ©   (2005-01-05 00:25) [10]

>> GuAV

Тебе жалко её что ли, флаг с ней с программой, она же не человек, мы ведь о людях думаем(ну когда прогаем).

Али нет???


 
GuAV ©   (2005-01-05 00:48) [11]

STK ©   (05.01.05 0:25) [10]

Прогу - нет. Но ресурсы которые не освобождаются (ну там атомы всякие) - жалко. Потом, может она что-о при выходе сохраняет...


 
STK ©   (2005-01-05 16:50) [12]


> GuAV ©   (05.01.05 00:48) [11]
> STK ©   (05.01.05 0:25) [10]
>
> Прогу - нет. Но ресурсы которые не освобождаются (ну там
> атомы всякие) - жалко. Потом, может она что-о при выходе
> сохраняет...


Думш оба варианта не оставляют за собой отпечаток?

Или твой вариант Лишён таких недостатков. Если да то кратко поясни почему.

И к стати(е) мне не надо Ждать пока прога отработает:WaitForInputIdle(hProcess, INFINITE); т.к. как помните Масяня как проиграет сама(Редиска эдакая) не закрывается.

И не могли бы кто ни будь мне пояснить что делает эта фунца и какой параметр выдаёт.

Заранее ещё раз спасибо.


 
GuAV ©   (2005-01-05 17:12) [13]


> Или твой вариант Лишён таких недостатков. Если да то
> кратко поясни почему.


В MSDN в разделе про TerminateProcess есть пояснение. Не выполнится не только код завершения поцесса, но и код завершения библиотек

[6] c добавленным CloseHandle(hThread); CloseHandle(hProcess); лишен этих недостатков, т.к. закрывает приложение "нажатием на кнопку закрыть прграмно". Т.е. если есть несохранённый текст, будет выдан запрос на сохранение.

Вообще если снять задачу через Ctrl+Alt+Del то windows сначала делает что-то вроде моего кода, потом ждёт (это можно сделать WaitForSingleObject) и уже потом прибивает процесс.


> WaitForInputIdle(hProcess, INFINITE);

Ждёт когда процесс начнёт ожидать ввода пользователя. Обычно это означает "зверешение инициализации". Возвращает результат: дождались, нет, ошибка. Всё описано опять же в MSDN или в справке.


 
STK ©   (2005-01-05 22:04) [14]


> GuAV ©   (05.01.05 17:12) [13]

Спасибо за пояснения. Real.



Страницы: 1 вся ветка

Текущий архив: 2005.02.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.029 c
6-1102167604
mazai
2004-12-04 16:40
2005.02.20
как отключить сообщения об ошибках?


1-1107781856
mariya_mezenceva
2005-02-07 16:10
2005.02.20
vk_insert


1-1107331582
MakedoneZ
2005-02-02 11:06
2005.02.20
Почему неоткрывается frmGraph?


14-1106939309
Ломброзо
2005-01-28 22:08
2005.02.20
"Что, уже началось?" :-)


8-1099136406
Tatarin
2004-10-30 15:40
2005.02.20
MP2 MP3