Страница: 1 | 2 |
Вопрос: Закрыть дубликат процесса.
Добавлено: 19.12.05 11:46
Автор вопроса: LamerOnLine | ICQ: 334781088
Вопрос такой - есть activex.exe, без окон, в списке задач не значится. При запуске могу определить PrevInstance, но как определить какому из процессов вызывать TerminateProcess? Мне нужно закрыть предыдущий, имена процессов одинаковые.
Ответы
Всего ответов: 23
Номер ответа: 1
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #1
Добавлено: 19.12.05 12:06
Вставь код, который при загрузке твоего Актива.ехе читал бы значение с реестра. Если там значение="я уже есть", значит новый инстанс выгружается, если значение="" ,значит грузимся дальше,сохраняем значение "я уже есть" в реестре, но при выходе удаляем его.
Номер ответа: 2
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #2
Добавлено: 19.12.05 12:17
Фокус в том что через PrevInstance я легко могу узнать запущен один такой активикс или несколько. Мне нужно выгрузить предыдущие и оставить только последний. Добавлять форму в проект только ради этого совсем не хочется, а больше отличить один процесс от другого безглючным способом не удается
Номер ответа: 3
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #3
Добавлено: 19.12.05 12:52
Пока вроде решил задачу не лучшим способом - получаю через EnumProcesses ID всех процессов, затем сравниваю ID процесса с аналогичным именем exe файла с GetCurrentProcessId и мочу гада. Но что-то не очень красиво...
Номер ответа: 4
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #4
Добавлено: 19.12.05 13:00
Private Const MAX_PATH As Long = 260&
Private Const MAX_MODULE_NAME32 As Long = 256&
Private Const TH32CS_SNAPPROCESS As Long = &H2
Private Const TH32CS_SNAPMODULE As Long = &H8
Private Const WM_SYSCOMMAND As Long = &H112
Private Const SC_CLOSE As Long = &HF060&
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type
Private Type MODULEENTRY32
dwSize As Long
th32ModuleID As Long
th32ProcessID As Long
GlblcntUsage As Long
ProccntUsage As Long
modBaseAddr As Long
modBaseSize As Long
hModule As Long
szModule As String * MAX_MODULE_NAME32
szExeFile As String * MAX_PATH
End Type
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByRef lParam As Any) As Long
Private Declare Function Process32First Lib "kernel32.dll" ( _
ByVal hSnapshot As Long, _
ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32.dll" ( _
ByVal hSnapshot As Long, _
ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Module32First Lib "kernel32.dll" ( _
ByVal hSnapshot As Long, _
ByRef lpme As MODULEENTRY32) As Long
Private Declare Function Module32Next Lib "kernel32.dll" ( _
ByVal hSnapshot As Long, _
ByRef lpme As MODULEENTRY32) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" ( _
ByVal hObject As Long) As Long
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32.dll" ( _
ByVal dwFlags As Long, _
ByVal th32ProcessID As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" ( _
ByVal hWnd As Long, _
ByRef lpdwProcessID As Long) As Long
Private Declare Function EnumWindows Lib "user32.dll" ( _
ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long
Private lpdwFoundProcessID As Long
Public Sub CloseExe(ByVal sExeForClosing As String)
Dim lRetval As Long
' Найти PID по экзешнику
lpdwFoundProcessID = GetProcessID(sExeForClosing)
If lpdwFoundProcessID > 0 Then _
lRetval = EnumWindows(AddressOf EnumWindowsProc, ByVal 0&
End Sub
Private Function GetProcessID(ByVal szExeFile As String) As Long
Dim lRetvalP As Long
Dim lRetvalM As Long
Dim lhSnapshotP As Long
Dim lhSnapshotM As Long
Dim lppe As PROCESSENTRY32
Dim lpme As MODULEENTRY32
Dim sExeFile As String
lhSnapshotP = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&
If lhSnapshotP = 0 Then Exit Function
lppe.dwSize = Len(lppe)
lRetvalP = Process32First(lhSnapshotP, lppe)
Do While lRetvalP
lhSnapshotM = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, lppe.th32ProcessID)
If lhSnapshotM = 0 Then Exit Function
lpme.dwSize = Len(lpme)
lRetvalM = Module32First(lhSnapshotM, lpme)
Do While lRetvalM
sExeFile = StringFromBuffer(lpme.szExeFile)
If LCase(sExeFile) = LCase(szExeFile) Then
GetProcessID = lpme.th32ProcessID
GoTo ExitFunction
End If
lRetvalM = Module32Next(lhSnapshotM, lpme)
Loop
lRetvalP = Process32Next(lhSnapshotP, lppe)
Loop
ExitFunction:
lRetvalP = CloseHandle(lhSnapshotP)
lRetvalM = CloseHandle(lhSnapshotM)
End Function
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
Dim lpdwProcessID As Long
Dim lRetval As Long
lRetval = GetWindowThreadProcessId(hWnd, lpdwProcessID)
If lRetval > 0 Then
If lpdwProcessID = lpdwFoundProcessID Then
Call SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, ByVal 0&
End If
End If
EnumWindowsProc = 1
End Function
Public Function StringFromBuffer(ByVal sBuffer As String) As String
Dim lPos As Integer
lPos = InStr(sBuffer, vbNullChar)
If lPos > 0 Then
StringFromBuffer = Left$(sBuffer, lPos - 1)
Else
StringFromBuffer = sBuffer
End If
Debug.Print StringFromBuffer
End Function
Использование - CloseEXE("C:\Windows\System32\MyActiveX.exe"
Прикол в том, что закрываються не только ЕХЕ-шники с окнами, но без них, а также DLL, TLB и другие инстансы. Вот например, попробуй вот так:
CloseEXE("C:\Program Files\Microsoft Visual Studio\VB98\VB6IDE.DLL".
ЗЫ. Если, конечно, у тебя стоит VB6
Номер ответа: 5
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #5
Добавлено: 19.12.05 13:11
Да, я тоже думал сначала снэпшотами, но потом решил все-таки через простую енумерацию. Дюжа снэпшоты тормозные, ИМХО.
Номер ответа: 6
Автор ответа:
Victor
ICQ: 345743490
Вопросов: 42
Ответов: 385
Web-сайт:
Профиль | | #6
Добавлено: 19.12.05 17:29
Это ж твой контрол. Так сделай так, чтобы он по таймеру отслеживал, не появилось ли там значение, указывающее на то, что ему пора завершиться.
Ну например.
При запуске делаем так:
А где-нибудь в таймере вот так:
If CLng(GetSetting(App.title, "Hfpltk", "CurInstanceID", 0))<>App.hInstance Then
End
End If
End Sub
Тогда при запуске нового старый увидит, что правильный процесс уже не он, он сам закроется.
Способ 2. Посылать сообщение DDE. Но я с этим так и не разобрался, так что это не ко мне.
Номер ответа: 7
Автор ответа:
XPress
ICQ: 249007960
Вопросов: 3
Ответов: 8
Профиль | | #7
Добавлено: 21.12.05 06:22
А как быть в моем случае??? если у меня есть формы! И копии моей проги запущены с разными пользователями? А кто нить знает как посылать сообщения DDE??? Я пробовал посылать команды старой запущенной проге с помощью WinSock но что то не катит такой метод! Плззз.....Жду ответа!
Номер ответа: 8
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #8
Добавлено: 21.12.05 11:22
А чем твой случай принципиально отличается? И что значит "запущены с разными пользователями"? А DDE, ИМХО, нафиг тут не надо, ибо технология устаревшая и в данном случае ненужная.
По поводу Winsock - они что, у тебя на разных машинах запущены?
P.S. Насчет форм - если параметр Unattended Execution не установлен, то окно у проекта будет в
любом случае, так же как и App.Title. Даже если в проекте нет ни одной формы.
Номер ответа: 9
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #9
Добавлено: 21.12.05 12:34
любом случае, так же как и App.Title
Кстати, а за что этот параметр отвечает?
Номер ответа: 10
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #10
Добавлено: 21.12.05 12:50
Собственно, за то о чем написано в хелпе
Unattended Execution
Indicates that the project is intended to run without user interaction. Unattended projects have no interface elements. Any run-time functions such as messages that normally result in user interaction are written to an event log.
То есть, проект не имеет своих форм и элементов управления. MsgBox'ами тоже не пользоваться. Только логирование.
Если установлен этот параметр, то приложение не отображается в списке задач Task Manager'а, только в процессах. В противном случае будет таск с псевдоокном, стандартной иконкой и заданным App.Title.
Номер ответа: 11
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #11
Добавлено: 21.12.05 13:00
У кого он есть, а у кого нет.
Кстати (чуть отклонусь от топика, сорри) где можно МСДН скачать - именно скачать и именно для ВБ6 (мне всё равно скока занимает)
Номер ответа: 12
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #12
Добавлено: 21.12.05 13:14
Собсно, у мелкософта. Он у них на свободное скачивание выложен. Поройся на их серваке, я прямую ссылку не помню.
А именно по VB6 - это тебе старый нужен, тут хез, мож и есть где, я с дисков ставил от шестой студии.
Как вариант - взять хелп от пятого, там он в hlp файлах, открывать можно в ручную. Но там только по VB, никаких АПИ и прочей требухи.
Номер ответа: 13
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #13
Добавлено: 21.12.05 14:28
Да искал я.... На ихнем серваке уже винты горячие... Можт кто-нить знает где взять энтот хелпер. Ато у меня только один chm-файл, и то с мелкософтовского офиса взял
Номер ответа: 14
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #14
Добавлено: 21.12.05 14:30
Кстати, при запуске проги с другим именем PrevInstance не катит
Номер ответа: 15
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #15
Добавлено: 21.12.05 15:50
В моем случае запуск проги с другим именем невозможен в принципе. Разве что скопировать и переименовать exe. Title у приложения нет, есть только имя exe файла процесса.
А хелпер может по почте заказать можно, не спрашивал?