Завершение чужой программы из моей
Очень был бы рад исходнику или хотя бы примерному коду функции, которая это дело делает.
В ВинАПИ есть функция, которая позволяет получить список процессов. У каждого из процессов есть pid, это типа его идентификатор. Имеешь его, даешь команду через winexec (опять-же не помню :)) на завершение процесса с этим pid. Я еще поковыряю мануалы, у меня это где-то есть...
\\\ Часть 1 из 2 \\\\\\\\\\\\\\\\
Шаг 32 - Сканируем список процессов.
В прошлом шаге мы убедились, что у нас нет инструмента, с помощью которого мы можем просмотреть список всех процессов в Windows 98. Но мы можем такой инструмент создать. В свое время Microsoft создала специальную библиотеку ToolHelp.Dll, используя которую можно получить доступ к информации о системе. Вот мы с ее помощью и попробуем получить список процессов.
Итак, давайте создадим приложение на базе MFC AppWizard и как Dialog Based. Поместим на диалог кнопку и элемент управления ListBox, который свяжем с помощью ClassWizard с переменной m_List1 типа Control и напишем код реакции на нажатие кнопки:
// ScanProcessDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ScanProcess.h"
#include "ScanProcessDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "tlhelp32.h"
......
void CScanProcessDlg::OnScan()
{
m_List1.ResetContent();
HANDLE hSnap;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == NULL)
{
AfxMessageBox("Error Load ToolHelp");
}
PROCESSENTRY32 proc;
if (Process32First(hSnap, &proc))
{
m_List1.AddString(proc.szExeFile);
while (Process32Next(hSnap, &proc))
{
m_List1.AddString(proc.szExeFile);
}
}
}
В заголовочном файле tlhelp32.h находятся описания функций.
Если вы посмотрите результат работы этой программы, то увидите, что процессов намного больше. В том числе и сможете увидеть процессы, которые не видели в прошлом шаге.
Шаг 33 - Win98 как NT. Убиваем процесс.
Итак, мы с Вами получили список процессов. Теперь на диалоговую панель добавим новую кнопку Terminate Process. Если в списке выделен процесс, то по нажатию на эту кнопку процесс будет удален. Вот код.
void CScanProcessDlg::OnTernimate()
{
int inIndex;
inIndex=m_List1.GetCurSel();
if (inIndex!=LB_ERR)
{
CString csExName;
m_List1.GetText(inIndex,csExName);
HANDLE hSnap;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == NULL)
{
AfxMessageBox("Error Load ToolHelp");
}
else
{
PROCESSENTRY32 proc;
if (Process32First(hSnap, &proc))
{
if (csExName==proc.szExeFile) TerminateProcess(hSnap,0);
while (Process32Next(hSnap, &proc))
{
if (csExName==proc.szExeFile)
{
HANDLE ProcessHandle=NULL;
ProcessHandle = OpenProcess(SYNCHRONIZE, TRUE, proc.th32ProcessID);
if (ProcessHandle!=NULL)
{
TerminateProcess(ProcessHandle,0);
CloseHandle(ProcessHandle);
Sleep(5000);
OnScan();
}
else AfxMessageBox("Not Open Process");
}
}
CloseHandle(hSnap);
}
}
}
else AfxMessageBox("Select Process");
}
Сначала проверяем выбран ли элемент списка if (inIndex!=LB_ERR). Если выбран пробегаем по процессам. Код повторяется как при сканировании процесса. Конечно можно было создать массив при сканировании. Но процесс дело тонкое, то он есть, а то его нет. Лучше на мой взгляд просканировать еще раз. Если его находим, то открываем с помощью функции OpenProcess(). Дальше спокойно вызываем TerminateProcess.
HANDLE OpenProcess
(
DWORD dwDesiredAccess, // флаг доступа
BOOL bInheritHandle, // флаг наследования
DWORD dwProcessId // идентификатор процесса
);
Идентификатор процесса мы берем из структуры PROCESSENTRY32 - это переменная, которая заполняется при запуске.
BOOL TerminateProcess(
HANDLE hProcess, // Указатель процесса
UINT uExitCode // Код возврата процесса
);
Задержку я сделал для того, чтобы обновить список через некоторое время, так как удаление процесса не моментальное дело. Программу я испытывал на Windows 98. Удаляет все процессы кроме Kernel :) Оно и понятно, сам себя удалять не будешь. При этом помните шаг "Шаг 31 - Программа, которая не удаляется из списка задач". Отсюда удалить ее можно и это получается. Кроме того удалить можно и процесс оболочки. Все работает как в NT. Отсюда рождается много интересных вещей. Например, можно выяснить почему тормозит Windows. Многие процессы просто не нужны для работы. Попробуйте поудаляйте.
Тем более, что при этом программа (закрываемая) не получает никаких сообщений и не имеет возможности сохранить то, что успела наработать.
Если известен Caption - лучше воспользоваться API-шной FindWindow и послать окну wm_quit (а если будет сопротивляться, тогда уж и процесс прибить можно :))
Unexpected, поддерживаю!;)
[COLOR=red]*Thank*, RESPECT![/COLOR] ;)
Цитата:
Originally posted by Dmitri
Подскажите, пожалуйста, как реализовать завершение чужой программы из моей, зная при этом Caption и имя .exe проги, которую надо закрыть? Т.е., фактически надо "прибить" процесс нужной мне проги из моей проги. Как такое сделать?
Очень был бы рад исходнику или хотя бы примерному коду функции, которая это дело делает.
Подскажите, пожалуйста, как реализовать завершение чужой программы из моей, зная при этом Caption и имя .exe проги, которую надо закрыть? Т.е., фактически надо "прибить" процесс нужной мне проги из моей проги. Как такое сделать?
Очень был бы рад исходнику или хотя бы примерному коду функции, которая это дело делает.
Кто не в курсе - поиск работает.
http://forum.codenet.ru/showthread.php?s=&threadid=25868&highlight=PROCESSENTRY32
http://forum.codenet.ru/showthread.php?s=&threadid=26222&highlight=PROCESSENTRY32
и т.д.