Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 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-сайт: hw.t-k.ru
 Профиль | | #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)
    ;Dim hProcess As Long, exitCode As Long
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, Shell(sCmdLine, Val(sParam)))
    ;Do
        Call GetExitCodeProcess(hProcess, exitCode)
        Sleep (&H66)
        ;DoEvents
    Loop While exitCode = STATUS_PENDING
    
    Call CloseHandle(hProcess)
End Sub

Ответить

Номер ответа: 3
Автор ответа:
 DaSharm



ICQ: 780477 

Вопросов: 72
Ответов: 1297
 Web-сайт: dasharm.com
 Профиль | | #3
Добавлено: 30.10.04 11:50
2SNE: по-ламерски.
Лучше юзай CreateProcess и :
1.WaitForSingleObject с флагом Infinite. Правда, твоя прога подвиснет до завершения процесса запущенной проги...
2.GetExitCodeProcess в таймере, тогда прога ваще не будет подвисать.

Ответить

Номер ответа: 4
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #4
Добавлено: 30.10.04 14:10
Было лень писать/искать, взял что под руку попалось...

Ответить

Номер ответа: 5
Автор ответа:
 shareman



Вопросов: 11
Ответов: 37
 Профиль | | #5 Добавлено: 30.10.04 16:36
Option Explicit

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
GetExitCodeProcess в таймере, тогда прога ваще не будет подвисать


Использование таймера - дурной тон, и приём не менее ламерский.

Запускаем тот же калькулятор из отдельного thread'a и в этом же отдельном thread'е ждём WaitForSingleObject.

Ничего не виснет, и программа, запустившая калькулятор, может заниматься своими делами. На выходе из thread'a оповещаем основную программу, что WaitForSingleObject сработала, например через SendMessage hWnd,WM_USER+???? или RaiseEvent

Ответить

Номер ответа: 7
Автор ответа:
 DaSharm



ICQ: 780477 

Вопросов: 72
Ответов: 1297
 Web-сайт: dasharm.com
 Профиль | | #7
Добавлено: 30.10.04 17:52
Запускаем тот же калькулятор из отдельного thread'a

Хи...Создай мне нормально работающий поток в NT, если ты такой умный...

Ответить

Номер ответа: 8
Автор ответа:
 DaSharm



ICQ: 780477 

Вопросов: 72
Ответов: 1297
 Web-сайт: dasharm.com
 Профиль | | #8
Добавлено: 30.10.04 18:00
Ещё, кстати, вариант достоен ламерсок премии, но решает поставленную задачу:
Создать AktiveX.exe, юзать именно его для создания процесса и WaitForSingleObject, вот тогда можно будет передавать данные "родительской" проге через
SendMessage hWnd,WM_COPYDATA без каких либо проблем. Также можно накодить динамическую библу и импортировать ф-цию запуска из неё. МОгу накодить, размер будет приблизительно 7-14 кб

Ответить

Номер ответа: 9
Автор ответа:
 DaSharm



ICQ: 780477 

Вопросов: 72
Ответов: 1297
 Web-сайт: dasharm.com
 Профиль | | #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-сайт: dasharm.com
 Профиль | | #12
Добавлено: 30.10.04 18:59
На чём написан твой примерчик?На ВБ?Не шути...

Ответить

Номер ответа: 13
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #13
Добавлено: 30.10.04 19:25
А почему бы и нет, к примеру я могу создать поток который не рушит прогу... и ничего, другое дело что все это равновесие настолько шатким получается, что и чихнуть страшно ;)

ЗЫ
Зачем поток !? Ну вот положим дождались мы завершения процесса, и что !? Изменить значение переменной, а там, в основном потоке, по таймеру что-ль следить за переменной? Все равно из потока мы ничего не можем вывести, ни MsgBox, ни с формой поработать, ни с конролами...
Т.о. я несколько не понимаю смысла этого потока и как его можно практически использовать...

ЗЗЫ
Т.о. мой код наиболее компактен и приближен к суровым условиям VB ;)

Ответить

Номер ответа: 14
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #14
Добавлено: 30.10.04 19:31
оповещаем основную программу, что WaitForSingleObject сработала, например через SendMessage hWnd,WM_USER+????


Тогда уж PostMessage, я сомневаюсь что поток дождется возврата из той АПИ что ты предложил...

А теперь подумаем что же для этого понадобится еще? правильно:
1. Окно
2. Сабклассинг окна

Я не думаю что из-за ожидания завершения стоит создавать такой наворот...

(имхо)

Ответить

Номер ответа: 15
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #15 Добавлено: 30.10.04 20:00
Поток позволит выполнять какие-либо другие действия, если необходимо, хотя бы такие первоочередные вещи, как перерисовать окно при необходимости. При этом не создавая бесполезной суеты внутри цикла или по срабатыванию таймера

О Post\SendMessage: делал именно через SendMessage, хотя разница непринципиальная, если оконная процедура не завалена непрерывным потоком сообщений.

Не знаю как с циклом или таймером, а через запуск процесса из отдельного потока позволяет запускать неоднократно тот же калькулятор, не ожидая закрытия предыдущего, и закрытие каждого экземпляра калькулятора исправно оповещает основную прогу о своем завершении.

Зачем это нужно? Не знаю, возможно, что:
1. Это правильней
2. Более гибко
3. Меньше нагружается проц
4. Менее "ламерски" (безотносительно личностей)

Если на всё это не обращать внимания, можно делать как угодно, в т.ч. и в цикле, и с таймером.

Ответить

Страница: 1 | 2 | 3 | 4 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам