Visual Basic, .NET, ASP, VBScript
 

   
   
     

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

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

 

  Вопрос: CreateProcess,hProcess Добавлено: 20.09.06 16:09  

Автор вопроса:  vall

Я с екселя запускаю другую программу("Металикс")
 
RetVal = CreateProcessA(vbNullString, "C:\Metalix\cncKad2006.85\gkadw.exe", 0&, 0&, 1&, _
        NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc)


и нахожу его хэндл так:

hwnd = GetForegroundWindow


Но это не всегда работает(не тот хэндл берет иногда,
например берет хэндл самого екселя)

Можно ли наверняка поймать хэндл "Металикса" с помощью
hProcess? Что-то сам не могу, я редко этим занимаюсь!

hwnd = proc.hProcess

Ответить

  Ответы Всего ответов: 33  

Номер ответа: 1
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #1 Добавлено: 20.09.06 18:00
Интересно как? Если ты создал процесс - это еще не означает что процесс создал окно. Нужен либо хук (что для тебя, ИМХО, сложновато), либо задержка.
Для примера

'код формы
Option Explicit
Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As Any, lpProcessInformation As Any) As Long
Private Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Type PROCESS_INFORMATION
        hProcess As Long
        hThread As Long
        dwProcessId As Long
        dwThreadId As Long
End Type

Private Type STARTUPINFO
        cb As Long
        lpReserved As Long
        lpDesktop As Long
        lpTitle As Long
        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 ThreadID As Long

Private Sub Command1_Click()
Dim RetVal As Long
Dim PI As PROCESS_INFORMATION
Dim SI As STARTUPINFO
SI.cb = Len(SI)
RetVal = CreateProcess(vbNullString, "notepad", ByVal 0&, ByVal 0&, 0, 0, ByVal 0&, vbNullString, SI, PI)
ThreadID = PI.dwThreadId
End Sub

Private Sub Command2_Click()
Dim WinCaption As String
EnumThreadWindows ThreadID, AddressOf EnumThreadWndProc, 0
MsgBox "Window " & hWndMain
WinCaption = Space(256)
GetWindowText hWndMain, WinCaption, 256
MsgBox Trim(WinCaption)
End Sub


'код модуля
Option Explicit
Public hWndMain As Long

Public Function EnumThreadWndProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
hWndMain = hwnd
EnumThreadWndProc = 0
End Function

Можешь проверять хоть по таймеру пока окно не будет создано.

Ответить

Номер ответа: 2
Автор ответа:
 HACKER


 

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

Вопросов: 236
Ответов: 8362
 Профиль | | #2 Добавлено: 20.09.06 20:42
Может запускать процесс проще?

Shell "lala.exe"

ShellExecute (API)...

Может хендел искать по имени окна?
FindWindow

или оно заранее не извесно?

Ответить

Номер ответа: 3
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #3
Добавлено: 21.09.06 00:20
Почитайте про структуру lpProcessInformation As Any, которая на самом деле не Any, а PROCESS_INFORMATION. Передавать нужно по ссылке, ибо туда возвращаются данные о процессе:
hProcess
hThread
dwProcessId
dwThreadId

Ответить

Номер ответа: 4
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #4
Добавлено: 21.09.06 00:30
Итак, час был поздний, немного мозг отключается. Тут нужно знать несколько вещей. Если окно точно появляется, то просто FindWindow по классу и проверка какому процессу оно принадлежит. Если и класс меняется и заголовок, то EnumWindows и проверять хэндл процесса-хозяина. А так цикл с FindWindow самое то вроде.

Ответить

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



Вопросов: 6
Ответов: 171
 Профиль | | #5 Добавлено: 21.09.06 03:29

hWnd=FindWindow("","NameOfWindow";) or class 'FindWindow("Class","";)

If GetWindowThreadProcessId(hWnd, lpdwProcessId) then

   hWnd=точно тот что нужен
end if

Ответить

Номер ответа: 6
Автор ответа:
 vall



Вопросов: 6
Ответов: 31
 Профиль | | #6 Добавлено: 21.09.06 09:07

У меня так и работает программа:
 
RetVal = Shell("C:\Metalix\cncKad2006.85\gkadw.exe", 1)
   
hwnd = FindWindow(vbNullString, "No Part  'F'  FINNPOWER / F625      20FI-C   - cncKad2006 V8.0";)
   
PostMessage hwnd, WM_COMMAND, 44011, 0
--------------------------------------

Но приходят каждый месяц апгрэйты(обновления) для
Металикса и при этом меняется его номер- "cncKad2006 V8.098" Чтобы каждый раз не перелопачивать все программы
(у меня их много) для замены номера, я использовал:

hwnd = GetForegroundWindow()


А это иногда хватает другие окна!

Буду пробовать совет от LamerOnLine, пример его работает!

Ответить

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



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #7 Добавлено: 21.09.06 11:12
Вроде тема исчерпана, но все же поприкалываюсь :)
Может запускать процесс проще?

Может. Но будем исходить из условия.
Может хендел искать по имени окна?

Вариант хорощ если заголовок окна известен и неизменен. И если запущена лишь одна копия. Иначе... ну, сам понимаешь :)
Почитайте про структуру lpProcessInformation As Any, которая на самом деле не Any

ЛОЛ, без коментариев испадстула :))) Мозг у тя и впрямь отключился. Шучу :)
Ra$cal, если ты ВНИМАТЕЛЬНО посмотришь на код, то увидишь - dwThreadId возвращается и используется для енумерации не ВСЕХ окон, а только окон ЭТОГО потока. Первое же окно в енумерации - искомое, поэтому возвращаем ноль. Чего еще то надо?

Ответить

Номер ответа: 8
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #8
Добавлено: 21.09.06 14:06
Теперь внимательно посмотри, какую функцию предложил я. Она находит все окна.
На счёт темы, можешь в цикле брать окна функцией GetForeGroundWindow и проверять вхождение слова cncKad2006. Вроде удобнее.
PS:Не стоит выпендриваться, если не знаешь меня. Над чудо умельцем, знатоком апи и асма хакером пожалуйста, с ним всё понятно, но вот мою персону - только если ты лучше меня, в чём я сильно сомневаюсь ;) Никаких понтов, просто не люблю выскочек, не обосновывающих своего поведения.

Ответить

Номер ответа: 9
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #9
Добавлено: 21.09.06 14:10
vall
Используй в цикле GetForeGroundWindow и проверяй заголовок на наличие фрагмента текста, который есть во всех версиях. cncKad2006. strin или как там называется функция.

Ответить

Номер ответа: 10
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #10
Добавлено: 21.09.06 14:17
Жаль сдесь нет функции редактирования сообщений...
vall: ещё скажи пожалуйста, какой класс у окна, которое ты хочешь поймать? Класс оч редко меняют, поэтому FindWindow по классу 100% будем легко находить. И всё сократится или к циклу или к слипу после запуска.

Ответить

Номер ответа: 11
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #11 Добавлено: 21.09.06 15:01
Ну как всегда. Ляпнет человек глупость, а потом обижается - мол, зря его обидели, он же тут единственный кто не ламер. Не нужно тут разборки устраивать, это никому неинтересно.
По сабжу - вообще непонятно. В каждой теме после того как решение уже найдено начинается поиск неоптимальных и бессмысленных вариантов. Люди, ну объясните мне - зачем искать по классам, кускам Caption'а и прочему барахлу, если по условию имеется ThreadId и одной функцией из него берется главное окно? Просто пофлудить нада? :)

Ответить

Номер ответа: 12
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #12
Добавлено: 21.09.06 15:22
Ну как всегда. Ляпнет человек глупость, а потом обижается - мол, зря его обидели, он же тут единственный кто не ламер. Не нужно тут разборки устраивать, это никому неинтересно.
Да, ляпнул глупость. Но не по незнанию, а по потере внимания. Сам исправился. Так что ты там ёрничаешь? Я написал, что час поздний. Когда сам будешь спать по 4 часа и менее в день и так неделю я посмотрю, что ты напишешь. Не хорошо не вникнув в ситуацию пытаться показать себя шутником. Здесь не весёлый разговор друзей, уважать надо людей. На этом, надеюсь, закончили. Надеюсь, пересмотришь своё поведение.
По сабжу - вообще непонятно. В каждой теме после того как решение уже найдено начинается поиск неоптимальных и бессмысленных вариантов. Люди, ну объясните мне - зачем искать по классам, кускам Caption'а и прочему барахлу, если по условию имеется ThreadId и одной функцией из него берется главное окно? Просто пофлудить нада? :)

Рассказываю, если сам не догоняешь.
Окно, которое появится первым, совсем не обязательно главное или то, которое нужно. У меня в программе, которая работает с хоткеями, создаётся невидимое окно, первым, а потом главное. Твой вариант отнюдь не оптимален и опасно крив, поэтому и продолжается обсуждение. Если изменится число невидимых окон, то бажность только увеличится. Поэтому нужн контроль за окнами. Пора отвыкать программить без единой проверки результата. И зачем использовать Enum, если есть имя класса окна? Чем это неоптимально, бессмысленно Ты очень не дальнозорок, и очень самоуверен. Слушай людей, собаку съевших на самоуверенности и отвержении любых слов, кроме своих. Учись думать наперёд и продумывать разные варианты. Слушать окружающих и делать здравый выбор без фанатизма. Ну а фраза
объясните мне - зачем искать по классам, кускам Caption'а и прочему барахлу, если по условию имеется ThreadId и одной функцией из него берется главное окно?
, это конечно позитиф :) Такие выводы без детального описания проблемы - видимо ты телепат ;)

vall: чем точнее описание, тем меньше флуда и точнее ответы, поэтому не поленись отвечать на заданные вопросы, это ведь тебе нужно, чтоб ответ был как можно более правильным

Ответить

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



Вопросов: 6
Ответов: 31
 Профиль | | #13 Добавлено: 21.09.06 15:51
To Ra$cal
Класс у Металикса всегда разный,
например так:
Afx:00400000:b:00010011:00000006:05B101E9

потом может быть так:
Afx:00400000:b:00010011:00000006:048C023D

To LamerOnLine
Вроде все сделал как в примере, но опять берет что-то,
что иногда найти не могу-что? и WinCaption не показывает!

RetVal = CreateProcessA(vbNullString, "C:\Metalix\cncKad2006.85\gkadw.exe", 0&, 0&, 1&, _
        NORMAL_PRIORITY_CLASS, 0&, vbNullString, si, pi)

ThreadID = pi.dwThreadId
 
Dim WinCaption As String
 EnumThreadWindows ThreadID, AddressOf EnumThreadWndProc, 0
MsgBox "Window " & hWndMain
WinCaption = Space(256)
GetWindowText hWndMain, WinCaption, 256
MsgBox Trim(WinCaption)


Это основной кусок кода, остальное то же, что в примере!

Ответить

Номер ответа: 14
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #14
Добавлено: 21.09.06 16:03
Тогда раз знаешь кусок названия окна Enum, как говорил LOL, и в обработчике IntStr(если не ошибаюсь) для каждого окна. Как только будет эта строка - значит ок. После запуска лучше поставить небольшую паузу, хотя как хочешь.
Нельзя просто брать первое окно, как же вы не поймёте. Всё равно надо проверять, это ж наивно, ожидать, что всегда будет везти.

Ответить

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



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #15 Добавлено: 21.09.06 16:20
2Ra$cal Хороший эпик написал, загляденье :) Большинство не читал, если по делу:
Окно, которое появится первым, совсем не обязательно главное или то, которое нужно

Такая ситуация должна обговариваться отдельно. Раз о ней не упоминалось - значит без надобности.
Я не говорил что приведенный мной вариант оптимален уже потому что я его и не оптимизировал, но он дает куда большие гарантии чем гадание на кофейной гуще типа InStr. Про класс окна вообще жесть. 90% софта имеют класс основного окна, зависящей от языка разработки. Запусти 20 разных VB приложений - у всех окон будет класс ThunderFormDC. Не показатель. А Enum, в отличие от FindWindow, проводится только по окнам нужного потока. В общем, спорить глупо, флудить лень :) Только, пжалста, не учи людей как себя вести. За порядком следит модератор. Ты вроде не из их числа.
2vall У тебя же поиск окна идет СРАЗУ после запуска процесса. В 90% случаев окно еще просто не создано. Добавь задержку или проверку в цикле.

Ответить

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

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



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