Модераторы: Akina

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Закрытие сторонней программы 
:(
    Опции темы
AHTUxPK
Дата 17.12.2011, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Всем доброго времени суток.

Делаю программу для удобного управления несколькими серверами Counter Strike на одном компьютере, одна из нужных мне функций - остановка сервера. Но проблема в том, что все сервера имеют одинаковое имя процесса, а в интернете я нашёл только завершение программы по её названию или по имени процесса. Подскажите, как сделать завершение работы определённой программы, зная, где она находится (или зная порт, который используется сервером и т.п.). 
Программа и сервера находятся на одном компьютере. (Все сервера работают в консольном режиме, процессы имеют одинаковые названия)

Заранее спасибо)

UPD Итоги

Это сообщение отредактировал(а) AHTUxPK - 30.1.2012, 15:46
PM MAIL WWW ICQ   Вверх
Дмит
Дата 19.12.2011, 09:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 21.4.2006
Где: г.Волгоград

Репутация: 1
Всего: 9



Цитата

управления несколькими серверами

Запуск сервера входит в управление? Если да, то запомни PID процесса и соответственно останавливай. Ещё, как вариант, можно различить процессы по времени работы, если есть окно, то по активности оного.
PM MAIL WWW   Вверх
AHTUxPK
Дата 24.12.2011, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Цитата(Дмит @ 19.12.2011,  09:24)

Запуск сервера входит в управление? Если да, то запомни PID процесса и соответственно останавливай.

Скромный вопрос, как?

Запускаю я так:
Код

ShellExecute 0, "open", Text1.Text & "\" & "hlds.exe", Text8.Text, Text1.Text, SW_SHOWNORMAL

text1 - расположение файла, text8 - параметры запуска файла. Может есть какой-то параметр запуска, по которому потом можно найти и закрыть процесс?

Это сообщение отредактировал(а) AHTUxPK - 24.12.2011, 16:38
PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 25.12.2011, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Хотя нашёл, что функция shell возвращается pID - попробую с ней поработать

Подскажите, как в этой функции задавать рабочую папку?

Это сообщение отредактировал(а) AHTUxPK - 25.12.2011, 22:56
PM MAIL WWW ICQ   Вверх
Дмит
Дата 26.12.2011, 08:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 21.4.2006
Где: г.Волгоград

Репутация: 1
Всего: 9



Цитата

задавать рабочую папку?

у каждого сервера своя рабочая папка при одном запускаемом файле?
тогда возможно указать в параметрах.
как Вы запускаете в ручную? используете параметры? 
PM MAIL WWW   Вверх
AHTUxPK
Дата 26.12.2011, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Цитата(Дмит @ 26.12.2011,  08:54)
у каждого сервера своя рабочая папка при одном запускаемом файле?
тогда возможно указать в параметрах.
как Вы запускаете в ручную? используете параметры?

Каждый сервер имеет отдельную папку и свой файл hlds.exe, запускаю так: 
pID = Shell(Путь_к_папке_с_файлом & "\" & "hlds.exe" & " " & Параметры_запуска, 1)

Чтобы запускать в ручную раньше использовал *.cmd файлы, которые находятся в каждой папке с сервером.

Вот как работает с помощью ShellExecute
Код

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Sub Command2_Click()
If Text2.Text = "" Then 'Если строка с указанной папкой сервера пуста - ничего не делаем, а если не пустая - запускаем:
Else
ShellExecute 0, "open", Text2.Text & "\" & "hlds.exe", Text9.Text, Text2.Text, SW_SHOWNORMAL ' Text2 - папка, где находится файл hlds.exe, Text9 - параметры запуска. Вот как раз предпоследний параметр функции отвечает за рабочую папку
End If
End Sub

Private Sub Command3_Click()
If Text3.Text = "" Then
Else
ShellExecute 0, "open", Text3.Text & "\" & "hlds.exe", Text10.Text, Text3.Text, SW_SHOWNORMAL ' тект3- уже рабочая папка другого севера, с файлом hlds.exe. текст10- параметры.
End If
End Sub


Это сообщение отредактировал(а) AHTUxPK - 26.12.2011, 09:33
PM MAIL WWW ICQ   Вверх
Дмит
Дата 27.12.2011, 09:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 21.4.2006
Где: г.Волгоград

Репутация: 1
Всего: 9



Shell("explorer.exe /e, D:\", 1)
ShellExecute(0, "open", "explorer.exe", "/e, D:\", "", SW_SHOWNORMAL)
Пример с explorer - D:\ папка для запуска. Не знаю то ли Вы имели ввиду.


PM MAIL WWW   Вверх
AHTUxPK
Дата 27.12.2011, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Не, немного не то, у ShellExecute есть параметр, который прямо описывается как рабочая директория, поэтому вопроса по этой функции не возникает:

Private Declare Function ShellExecute Lib "shell32" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long 

Параметры:
hWnd – идентификатор родительского окна. Указывать родительское окно не обязательно, можно просто 0
lpOperation – операция выполняемая с файлом. Может иметь следующие значения: «open» - открыть файл (папку), «print» - печатать текстовой документ, «explore»
lpFile – файл или папка, которую нужно открыть
lpParameters – параметры открытия файла, т.ч. запуска приложения. Используется только при запуске приложений
lpDirectory – рабочая директория
nShowCmd – параметры окна открытого файла (приложения, директории)

А у функции Shell нет так отдельно вынесенного параметра, но она возвращает нужный pID...

Это сообщение отредактировал(а) AHTUxPK - 27.12.2011, 13:05
PM MAIL WWW ICQ   Вверх
Дмит
Дата 28.12.2011, 07:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 21.4.2006
Где: г.Волгоград

Репутация: 1
Всего: 9



Может CurDir после Shell ?
PM MAIL WWW   Вверх
AHTUxPK
Дата 29.12.2011, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Цитата(Дмит @ 28.12.2011,  07:44)
Может CurDir после Shell ?

Да не, не получается так... 
PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 3.1.2012, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Всё, подсказали точно как сделать на другом форуме.

получилось так:
Код

ChDrive расположение_файла
ChDir расположение_файла
pID = Shell(("hlds.exe") & " " & параметры_запуска, 1)

PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 3.1.2012, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Теперь осталось разобраться как закрывать программу, зная её pID, нагуглил я один способ:

Код

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Const PROCESS_ALL_ACCESS = &H1F0FFF

Private Sub Command1_Click()
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pID) ' зная pID процесса находим pHandle процесса
Text1.Text = TerminateProcess(pHandle, 0&) ' Возвращает 1, если процесс закрыт успешно
End Sub

Но это принудительное закрытие процесса.
Вот пост с 1 форума:
Цитата

Только как я недавно узнал, такой принудительный способ (а этим способом можно принудительно закрыть почти любую программу, естественно с потерей всех ее данных, потому как принудитено) оказывается не освобождает память из под используемых этой программой Dll и COM объектов, что не очень хорошо... хотя все пользуются, наверное надеются на win'ский диспетчер памяти, наверное он в состоянии разобраться с таким барахлом, по крайне мере в Xp... но все уже мои догадки

Более умные функции закрытия программы, обычно сначала работают через окно (hWnd), посылая ему команду о закрытии, тогда окно может закончить все свои дела и закрыться, а вот если оно например через 15 сек еще назакрылось (зависло там или очень сильно задумалось), то тогда уже принудительно через Terminate. 


Подскажите, кто знает, как получить hWnd окна (зная process ID и/или Handle) и передать окну определённое сочетание клавиш? (в моём случае Ctrl + C, ну закрытие консоли короче) Или просто мягкое закрытие программы?

Лучше конечно передача сочетания клавиш, она мне для другой программы пригодится...

Это сообщение отредактировал(а) AHTUxPK - 3.1.2012, 19:40
PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 6.1.2012, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Ура, кажется нашёл то, что нужно.

Получаем hwnd по pid.

В модуль:
Код

Public Const GW_HWNDNEXT = 2

Public Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long

Function ProcIDFromWnd(ByVal hwnd As Long) As Long
   Dim idProc As Long
   
   ' Get PID for this HWnd
   GetWindowThreadProcessId hwnd, idProc
   
   ' Return PID
   ProcIDFromWnd = idProc
End Function
      
Function GetWinHandle(hInstance As Long) As Long
   Dim tempHwnd As Long
   
   ' Grab the first window handle that Windows finds:
   tempHwnd = FindWindow(vbNullString, vbNullString)
   
   ' Loop until you find a match or there are no more window handles:
   Do Until tempHwnd = 0
      ' Check if no parent for this window
      If GetParent(tempHwnd) = 0 Then
         ' Check for PID match
         If hInstance = ProcIDFromWnd(tempHwnd) Then
            ' Return found handle
            GetWinHandle = tempHwnd
            ' Exit search loop
            Exit Do
         End If
      End If
   
      ' Get the next window handle
      tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
   Loop
End Function



В кнопку:
Код

hwnd  = GetWinHandle(pid)

PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 7.1.2012, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Научился отправлять нажатия клавиш по hwnd.

В модуль:
Код

Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const VK_CONTROL = &H11
Public Const VK_C = &H43
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101


В кнопку:
Код

PostMessage hwnd, WM_KEYDOWN, VK_CONTROL, 0
PostMessage hwnd, WM_KEYDOWN, VK_C, 0


Но никак не получается послать сочетание клавиш...

P.s. Что-то моя тема превращается в монолог    smile 

Это сообщение отредактировал(а) AHTUxPK - 7.1.2012, 15:10
PM MAIL WWW ICQ   Вверх
Дмит
Дата 10.1.2012, 12:03 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 21.4.2006
Где: г.Волгоград

Репутация: 1
Всего: 9



попробуйте нажать контрол до отсыла нажатия клавиши:
keybd_event(VK_CONTROL, 0, 0, 0)

и после отпустить:
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0)

впрочем в VB6 есть своя функция замена API (keybd_event)
и я пользуюсь SendMessage для отсыла, их нюансы читайте в Helpe.

Кстати, обязательно ли через клавиши, может быть так пройдёт как надо:
SendMessage(hwnd , WM_CLOSE, 1, 0)
или
SendMessage(hwnd , WM_QUIT, 1, 0)

Это сообщение отредактировал(а) Дмит - 10.1.2012, 14:01
PM MAIL WWW   Вверх
AHTUxPK
Дата 10.1.2012, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Первый способ помог, большое спасибо, только пришлось вставить одну строчку:

Код

Call keybd_event(VK_CONTROL, 0, 0, 0)
PostMessage hwnd, WM_KEYDOWN, VK_C, 0
Sleep (500)
Call keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0)


Ибо если вообще без задержки команда иногда не успевала доходить, а контрол уже отжимался

Это сообщение отредактировал(а) AHTUxPK - 10.1.2012, 21:22
PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 10.1.2012, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



Подытожу всю работу кусочками кода:

Запускаем программу и возвращаем её pID.
Код

ChDrive Расположение_файла
ChDir Расположение_файла
pID = Shell(("название_файла.exe") & " " & параметры_запуска, 1)


Определяем hwnd по pID:
Модуль:
Код

Public Const GW_HWNDNEXT = 2
Public Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long

Function ProcIDFromWnd(ByVal hwnd As Long) As Long
   Dim idProc As Long
   
   ' Get PID for this HWnd
   GetWindowThreadProcessId hwnd, idProc
   
   ' Return PID
   ProcIDFromWnd = idProc
End Function
      
Function GetWinHandle(hInstance As Long) As Long
   Dim tempHwnd As Long
   
   ' Grab the first window handle that Windows finds:
   tempHwnd = FindWindow(vbNullString, vbNullString)
   
   ' Loop until you find a match or there are no more window handles:
   Do Until tempHwnd = 0
      ' Check if no parent for this window
      If GetParent(tempHwnd) = 0 Then
         ' Check for PID match
         If hInstance = ProcIDFromWnd(tempHwnd) Then
            ' Return found handle
            GetWinHandle = tempHwnd
            ' Exit search loop
            Exit Do
         End If
      End If
   
      ' Get the next window handle
      tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
   Loop
End Function

Кнопка:
Код

hwnd = GetWinHandle(pID)


Посылаем сочетание клавиш для закрытия консоли по hwnd:
Модуль: 
Код

Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Public Const VK_CONTROL = &H11
Public Const VK_C = &H43
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101


И в код:
Код

Private Declare Sub Sleep Lib "kernel32" (ByVal milliseconds As Long)

Call keybd_event(VK_CONTROL, 0, 0, 0)
PostMessage hwnd, WM_KEYDOWN, VK_C, 0
Sleep (500) ' Можно и меньше, даже 100 прилично...
Call keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0)


Дмитрию большое спасибо за помощь.

Это сообщение отредактировал(а) AHTUxPK - 10.1.2012, 21:56
PM MAIL WWW ICQ   Вверх
AHTUxPK
Дата 15.2.2012, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 1.9.2011
Где: Пятигорск

Репутация: нет
Всего: нет



 smile У моей темы уже PR 1 даже стал, копипастят что ли активно, да простят меня модераторы за флуд) 

P.s. Никто так и не поможет с этой темой?(

Это сообщение отредактировал(а) AHTUxPK - 15.2.2012, 14:10
PM MAIL WWW ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "VB6"
Akina

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по VB обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • Используйте теги [code=vb][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Akina.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB6 | Следующая тема »


 




[ Время генерации скрипта: 0.1250 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.