Страница: 1 | 2 | 3 | 4 |
Вопрос: Shell - дождаться конца
Добавлено: 30.10.04 07:29
Автор вопроса: magish
Я запускаю любой EXE через Shell. Он работает и потом закрывается. КАК ОТЛОВИТЬ ЗАКРЫТИЕ ЕТОГО EXE ПРОГИ.
Я конечно могу сделать так чтобы он окно искал и если не найдёт то значит приложение закрылось, но у меня такая фича: я не знаю изначально заголовок окна.
ПОМОГИТЕ ОТЛОВИТь КОНЕЦ Shell операции плизз... Заранее спасибо...
Ответы
Всего ответов: 50
Номер ответа: 1
Автор ответа:
Mihalыch
ICQ: 373-509-101
Вопросов: 56
Ответов: 330
Профиль | | #1
Добавлено: 30.10.04 08:17
Ф-я Shell, если не ошибаюсь, возвращает ID запущенного процесса. Можно проверять наличие процесса… Как получить список запущенных процессов? - Поиск по форуму…
Номер ответа: 2
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #2
Добавлено: 30.10.04 08:24
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Const PROCESS_QUERY_INFORMATION As Long = &H400
Private Const STATUS_PENDING As Long = &H103&
Private Sub RunShell(sCmdLine As String, sParam As String)
 im hProcess As Long, exitCode As Long
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, Shell(sCmdLine, Val(sParam)))
 o
Call GetExitCodeProcess(hProcess, exitCode)
Sleep (&H66)
 oEvents
Loop While exitCode = STATUS_PENDING
Call CloseHandle(hProcess)
End Sub
Номер ответа: 3
Автор ответа:
DaSharm
ICQ: 780477
Вопросов: 72
Ответов: 1297
Web-сайт:
Профиль | | #3
Добавлено: 30.10.04 11:50
2SNE: по-ламерски.
Лучше юзай CreateProcess и :
1.WaitForSingleObject с флагом Infinite. Правда, твоя прога подвиснет до завершения процесса запущенной проги...
2.GetExitCodeProcess в таймере, тогда прога ваще не будет подвисать.
Номер ответа: 4
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #4
Добавлено: 30.10.04 14:10
Было лень писать/искать, взял что под руку попалось...
Номер ответа: 5
Автор ответа:
shareman
Вопросов: 11
Ответов: 37
Профиль | | #5
Добавлено: 30.10.04 16:36
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadID As Long
End Type
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long
Private Const NORMAL_PRIORITY_CLASS As Long = &H20&
Private Const INFINITE As Long = -1&
Private Const STARTF_USESHOWWINDOW As Long = &H1
Private Const SW_HIDE As Long = 0
Private Sub WaitProccess(ByVal Cmdline As String, _
Optional ByVal HideProccess As Boolean = False)
'structure to specify new window properties
Dim start As STARTUPINFO
'information about a newly created process and its primary thread.
Dim proc As PROCESS_INFORMATION
Dim Res As Long
If Trim(Cmdline) <> "" Then
'specifies the size, in bytes, of the structure.
start.cb = Len(start)
If HideProccess Then
'specifies which fields in this structure to use
start.dwFlags = STARTF_USESHOWWINDOW
'the default value the first time the function ShowWindow is called
start.wShowWindow = SW_HIDE
End If
Res = CreateProcessA(0&, Cmdline, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
Res = WaitForSingleObject(proc.hProcess, INFINITE)
Res = CloseHandle(proc.hProcess)
End If
End Sub
Private Sub Command1_Click()
'open the calculator - do not set HideProcess parameter to TRUE, or you'll have to close it with Task Manager
WaitProccess "calc.exe"
'notify that calculator is closed
MsgBox "Calculator is closed."
End Sub
Номер ответа: 6
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #6
Добавлено: 30.10.04 17:41
Использование таймера - дурной тон, и приём не менее ламерский.
Запускаем тот же калькулятор из отдельного thread'a и в этом же отдельном thread'е ждём WaitForSingleObject.
Ничего не виснет, и программа, запустившая калькулятор, может заниматься своими делами. На выходе из thread'a оповещаем основную программу, что WaitForSingleObject сработала, например через SendMessage hWnd,WM_USER+???? или RaiseEvent
Номер ответа: 7
Автор ответа:
DaSharm
ICQ: 780477
Вопросов: 72
Ответов: 1297
Web-сайт:
Профиль | | #7
Добавлено: 30.10.04 17:52
Хи...Создай мне нормально работающий поток в NT, если ты такой умный...
Номер ответа: 8
Автор ответа:
DaSharm
ICQ: 780477
Вопросов: 72
Ответов: 1297
Web-сайт:
Профиль | | #8
Добавлено: 30.10.04 18:00
Ещё, кстати, вариант достоен ламерсок премии, но решает поставленную задачу:
Создать AktiveX.exe, юзать именно его для создания процесса и WaitForSingleObject, вот тогда можно будет передавать данные "родительской" проге через
SendMessage hWnd,WM_COPYDATA без каких либо проблем. Также можно накодить динамическую библу и импортировать ф-цию запуска из неё. МОгу накодить, размер будет приблизительно 7-14 кб
Номер ответа: 9
Автор ответа:
DaSharm
ICQ: 780477
Вопросов: 72
Ответов: 1297
Web-сайт:
Профиль | | #9
Добавлено: 30.10.04 18:01
В случае с динам. библой это круче намного, поскольку поток создаеться сам, да ещё и внутри "родительского" процесса...
Номер ответа: 10
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #10
Добавлено: 30.10.04 18:27
Загляни в свой ящик, и увидешь нормально работающий трид
Номер ответа: 11
Автор ответа:
shareman
Вопросов: 11
Ответов: 37
Профиль | | #11
Добавлено: 30.10.04 18:53
DaSharm
Тот самый код, который я послал работает уже лет 5 и именно в NT, и никаких проблем не создает - в отличие от любого таймера.
Номер ответа: 12
Автор ответа:
DaSharm
ICQ: 780477
Вопросов: 72
Ответов: 1297
Web-сайт:
Профиль | | #12
Добавлено: 30.10.04 18:59
На чём написан твой примерчик?На ВБ?Не шути...
Номер ответа: 13
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #13
Добавлено: 30.10.04 19:25
А почему бы и нет, к примеру я могу создать поток который не рушит прогу... и ничего, другое дело что все это равновесие настолько шатким получается, что и чихнуть страшно
ЗЫ
Зачем поток !? Ну вот положим дождались мы завершения процесса, и что !? Изменить значение переменной, а там, в основном потоке, по таймеру что-ль следить за переменной? Все равно из потока мы ничего не можем вывести, ни MsgBox, ни с формой поработать, ни с конролами...
Т.о. я несколько не понимаю смысла этого потока и как его можно практически использовать...
ЗЗЫ
Т.о. мой код наиболее компактен и приближен к суровым условиям VB
Номер ответа: 14
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #14
Добавлено: 30.10.04 19:31
Тогда уж PostMessage, я сомневаюсь что поток дождется возврата из той АПИ что ты предложил...
А теперь подумаем что же для этого понадобится еще? правильно:
1. Окно
2. Сабклассинг окна
Я не думаю что из-за ожидания завершения стоит создавать такой наворот...
(имхо)
Номер ответа: 15
Автор ответа:
cresta
Вопросов: 117
Ответов: 1538
Профиль | | #15
Добавлено: 30.10.04 20:00
Поток позволит выполнять какие-либо другие действия, если необходимо, хотя бы такие первоочередные вещи, как перерисовать окно при необходимости. При этом не создавая бесполезной суеты внутри цикла или по срабатыванию таймера
О Post\SendMessage: делал именно через SendMessage, хотя разница непринципиальная, если оконная процедура не завалена непрерывным потоком сообщений.
Не знаю как с циклом или таймером, а через запуск процесса из отдельного потока позволяет запускать неоднократно тот же калькулятор, не ожидая закрытия предыдущего, и закрытие каждого экземпляра калькулятора исправно оповещает основную прогу о своем завершении.
Зачем это нужно? Не знаю, возможно, что:
1. Это правильней
2. Более гибко
3. Меньше нагружается проц
4. Менее "ламерски" (безотносительно личностей)
Если на всё это не обращать внимания, можно делать как угодно, в т.ч. и в цикле, и с таймером.