Дата: Воскресенье, 12.08.2012, 15:58 | Сообщение # 1
Частый гость
Зарегистрирован: 25.04.2011
Группа: Пользователи
Сообщений: 25
Статус: Offline
Помогите пожалуйста. У меня есть сервер некой игры(значения не имеет что за игра). иногда он слетает и вылазит окошко "прекращена работа программы "server.exe" закрыть программу и тд." Мне нужно отследить когда появляется окошко и закрыть его. код
PostMessage(FindWindow(Nil, 'server.exe'), WM_CLOSE, 0, 0);// не помогает (server.exe это то что написано в заголовке окна).. Так вот... Можно ли какнибудь еще отледить это окно если по заголовку не получается?
Дата: Воскресенье, 12.08.2012, 16:55 | Сообщение # 2
Авторитетный
Зарегистрирован: 22.01.2012
Группа: Модераторы
Сообщений: 702
Статус: Offline
зная путь до исполняющего файла:
Code
в uses "Windows", "SysUtils" и "Tlhelp32"
function KillTask(ExeFileName: string): integer; const PROCESS_TERMINATE=$0001; var ContinueLoop: BOOL; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; begin result := 0; FSnapshotHandle := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); while integer(ContinueLoop)<> 0 do begin if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then Result := Integer(TerminateProcess(OpenProcess( PROCESS_TERMINATE, BOOL(0), FProcessEntry32.th32ProcessID), 0)); ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);end; CloseHandle(FSnapshotHandle); end;
или вот мой вариант, вырвал из своего проекта, сам им постоянно пользуюсь...
Code
procedure TForm1.Button1Click(Sender: TObject); var h:hwnd; p:pchar; mk:Cardinal; begin h:=GetWindow(GetForegroundWindow,GW_HWNDFIRST); getmem(p,2000); GetWindowText(h,p,mk); while (pos('Блокнот',p)=0)and(h<>0) do begin h:=GetWindow(h,GW_HWNDNEXT); GetWindowText(h,p,mk); end; If (h <> 0 )then SendMessage((h),WM_SYSCOMMAND,SC_CLOSE,0); end; end.
кстати в моем варианте можно писать любую часть имени заголовка, например в данном случае закрывается окно с заголовком "Блокнот" в то время как его реальное название "Безымянный - Блокнот", можно написать "Безымянный" и оно так же закроется, вобщем смотрите сами что вам по душе...
Сообщение отредактировал xXxSh@dowxXx - Воскресенье, 12.08.2012, 16:57
Дата: Воскресенье, 12.08.2012, 18:54 | Сообщение # 3
Авторитетный
Зарегистрирован: 24.07.2011
Группа: Модераторы
Сообщений: 469
Статус: Offline
Code
getmem(p,2000);
А ХтО будет освобождать память?
В качестве первого варианта лучше использовать вот так:
Code
function GetProcessID(ProcessName: PAnsiChar): DWORD; var SnapshotHandle: DWORD; ProcessEntry32: TProcessEntry32; begin Result:=0; SnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if SnapshotHandle<>INVALID_HANDLE_VALUE then begin ProcessEntry32.dwSize:=SizeOf(TProcessEntry32); if Process32First(SnapshotHandle, ProcessEntry32) then while Process32Next(SnapshotHandle, ProcessEntry32) do begin if LStrCmp(ProcessEntry32.szExeFile, ProcessName)=0 then begin Result:=ProcessEntry32.Th32ProcessID; Break; end; end; CloseHandle(SnapshotHandle); end; end;
function KillProcess(ProcessName: PAnsiChar): Boolean; const PROCESS_TERMINATE=$0001; var hProcess, ProcessID: DWORD; begin Result:=false; ProcessID:=GetProcessID(ProcessName); if ProcessID<>0 then begin hProcess:=OpenProcess(PROCESS_TERMINATE, false, ProcessID); if hProcess<>INVALID_HANDLE_VALUE then begin Result:=TerminateProcess(hProcess, 0); CloseHandle(hProcess); end; end; end;
Сообщение отредактировал Волк-1024 - Воскресенье, 12.08.2012, 18:56
Дата: Понедельник, 13.08.2012, 05:35 | Сообщение # 4
Модератор
Зарегистрирован: 04.05.2010
Группа: Модераторы
Сообщений: 317
Статус: Offline
Я бы сделал так: Кидаешь таймер,ставишь интервал 50 или 10,или меньше.OnTimer пишешь или это:
Code
var h:hWnd; begin h:=FindWindow(nil, 'server.exe'); if h=0 then exit; SendMessage(h, {WM_DESTROY}WM_Close, 0,0); end;
Лучше использовать SendMessage,чем PostMessage,т.к SendMessage отправит сообщение окну и пошёл дальше,а PostMessage отправит сообщение окну и ждёт от него ответа,что окно получило это сообщение. В данном случае,это не к чему. или это
Code
const s='server.exe'; Var h:Hwnd; C:array [0..255] of char; begin H:=GetForeGroundWindow; if h=0 then exit; GetWindowTExt(H,C,255); if pos(s,C)<>0 then SendMessage(h, {WM_DESTROY}WM_Close, 0,0); end;
Похоже было у xXxSh@dowxXx,я убрал всё лишнее ))))
Дата: Понедельник, 13.08.2012, 11:30 | Сообщение # 5
Авторитетный
Зарегистрирован: 22.01.2012
Группа: Модераторы
Сообщений: 702
Статус: Offline
Neo, я может быть тебя удивлю, но у меня не сработал ни один из представленных тобой вариантов или может я такой запаренный после ночной смены и тупо ничего не соображаю
Дата: Понедельник, 13.08.2012, 14:08 | Сообщение # 6
Модератор
Зарегистрирован: 04.05.2010
Группа: Модераторы
Сообщений: 317
Статус: Offline
xXxSh@dowxXx, Точно,это я запарился со своим буткитом))))) Исправьте тип передаваемого сообщения WM_DESTROY на WM_Close в обоих примерах. Второй пример будет закрывать окно,если оно находится "наверху".Первый пример ищет нужное окно среди всех окон.Так что, первый пример надёжнее.
Сообщение отредактировал Neo - Понедельник, 13.08.2012, 14:16
Дата: Понедельник, 13.08.2012, 15:51 | Сообщение # 7
Частый гость
Зарегистрирован: 25.04.2011
Группа: Пользователи
Сообщений: 25
Статус: Offline
я вообще решил эту проблему несколько подругому(недождался)... Но столкнулся с другой проблемой. вообщем исходники я приложу. суть вот в чем. я отслеживаю появление окошка по названию процесса "WerFault.exe". Да я понимаю что если вылезет ошибка не с сервера моя прога ее закроет и я не узнаю в чем дело, но я готов рискнуть. После того как я закрыл это окно сервер гасится. и мне нужно его открыть. я атм использовал доволно грубый и (на мой взгляд) не очень удобный способ определения какой из 5ти серверов слетел. и мне нужно его запустить. Но почему-то на этом программа умолкает и не запускает нужный файл. в чем дело ума не приложу. все вроде до смешного просто сделал что б не ошибиться и все равно где-то ляп.