Visual Basic, .NET, ASP, VBScript
 

   
   
     

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

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

 

  Вопрос: Нетривиальная задачка по API Добавлено: 28.10.05 11:58  

Автор вопроса:  Comanche
Дано:
Хэндл процесса - как результат выполнения ShellExecuteEx.

Нужно:
Получить ID процесса.

Доп. требования:
Должно работать под любой версией ОС, начиная с NT 4.0.

Мысли после часа в Гугле и часа в MSDN'е:

1. Функция GetProcessId, которая явно решает эту задачу, существует только в XP w/SP1, Win2003 Server и в Висте. В предыдущих виндах её нет!!!

2. Материалов на эту тему очень мало.

3. В некоторых форумах задачу называют просто нерешаемой.

4. Удалось найти два решения "через одно место":

http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_10073493.html

и

http://www.eggheadcafe.com/ng/microsoft.public.win32.programmer.tools/post20380834.asp

Оба не тянут ни на быстрое, ни на универсальное, ни на надёжное решение.

Есть ещё идеи?

Ответить

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

Номер ответа: 1
Автор ответа:
 el-paso



Вопросов: 3
Ответов: 164
 Профиль | | #1 Добавлено: 28.10.05 13:40
А почему бы не использовать CreateProcess вместо ShellExecuteEx?
В последнем аргументе CreateProcess можно выкопать искомый ID...

Хотя, конечно, всё зависит от конкретной задачи...

Ответить

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



Вопросов: 87
Ответов: 459
 Профиль | | #2 Добавлено: 28.10.05 14:21
ОК, можно скомбинировать CreateProcess с FindExecutable - но всё равно точного аналога "запуска по файловой ассоциации" не получится - ведь не всегда командная строка предполагается равной "<exe-шник><пробел><файл>". Чтобы получить такой аналог, надо определить верную командную строку для данного типа файла, а для этого надо лезть в реестр, в HKCR находить соответствующий раздел shell\open\command, дёргать оттуда ключ, парсить его значение... ещё то удовольствие.

Если непонятно, о чём я, то вот shell\open\command для MSI-файлов:
"%SystemRoot%\System32\msiexec.exe" /i "%1" %*
и никак не просто
"%SystemRoot%\System32\msiexec.exe" "%1"


А мне нужна 100%-ная гарантия, что всё отработает корректно, как оно бывает при использовании ShellExecute/ShellExecuteEx.

Ответить

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



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #3 Добавлено: 28.10.05 17:41
А если не секрет - для чего это надо?
Задача в целом какая?

Ответить

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



Вопросов: 87
Ответов: 459
 Профиль | | #4 Добавлено: 28.10.05 18:32
Задача - манипулировать окнами, порождёнными процессом, запущенным через ShellExecuteEx. Нужно пройти по цепочке:

[B]ShellExecuteEx --> hProcess --> ProcessID[/B] --> <перебор его потоков> --> ThreadID (по каждому) --> EnumThreadWindows --> хэндлы окон --> и так далее...

Всё просто, кроме самого первого звена, о котором и речь.

Ответить

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



Вопросов: 87
Ответов: 459
 Профиль | | #5 Добавлено: 28.10.05 18:33
Пардон, очепятка:

кроме второго звена, разумеется, - hProcess --> ProcessID.

Ответить

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



ICQ: 345743490 

Вопросов: 42
Ответов: 385
 Web-сайт: vt-dbnz.narod.ru
 Профиль | | #6
Добавлено: 28.10.05 23:15
Можно вопрос. Что возвращает функция VB Shell? Не тот ли самый ID?

Ответить

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



Вопросов: 87
Ответов: 459
 Профиль | | #7 Добавлено: 28.10.05 23:42
Именно его и возвращает.
И что дальше?!

Ответить

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



ICQ: 345743490 

Вопросов: 42
Ответов: 385
 Web-сайт: vt-dbnz.narod.ru
 Профиль | | #8
Добавлено: 29.10.05 00:03
Я понял. Использование функции ShellExecute обязательно. Просто сразу хочется предложить использовать функцию Shell. Она, правда, не все умеет.

Ответить

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



ICQ: 345743490 

Вопросов: 42
Ответов: 385
 Web-сайт: vt-dbnz.narod.ru
 Профиль | | #9
Добавлено: 29.10.05 01:09
Нашел кое-что.

В MSDN Есть пример. TLIST называется.
Он делает то, что может помочь. А именно - получает полный список процессов вместе с их PID'ами. Дальше можно использовать функцию OpenProcess, которая дает хендл на процесс. Но я не уверен, что этот хендл совпадет с полученным из ShellExecuteEx. А если все нормально, то надо получить хендлы на каждый процесс, сравнить с имеющимся, и получить таким макаром PID.

Проблема в том, что там все сугубо на C, а я в нем плохо разбираюсь.
Вывалил файл: http://vt-dbnz.narod.ru/tlist.rar
(142KB)

Бяка в том, что это не слишком надежное решение, но ничего другого не видно.

Ответить

Номер ответа: 10
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #10 Добавлено: 29.10.05 02:32
Но я не уверен, что этот хендл совпадет с полученным из ShellExecuteEx.

Не совпадёт.

Ответить

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



Вопросов: 87
Ответов: 459
 Профиль | | #11 Добавлено: 29.10.05 13:10
Конечно не совпадёт! :)))

Более того, получение снэпшота системы - штука не быстрая...

На Релибе подсказали ссылку:
http://www.codeproject.com/win32/Remote.asp

Там эмуляция GetProcessId - в т.ч. и через недокументированные функции из NtDll.dll. Прикольно...

Ответить

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



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #12 Добавлено: 31.10.05 12:56
Ну можно пойти и с другого конца цепочки - GetWindowThreadProcessId :)

Ответить

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



Вопросов: 87
Ответов: 459
 Профиль | | #13 Добавлено: 31.10.05 14:20
Ну можно пойти и с другого конца цепочки - GetWindowThreadProcessId :)


Это не поможет - я же не знаю ProcessId, а знаю только его хэндл! и проблема-то заключается именно в их увязке!

Ответить

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



ICQ: 345743490 

Вопросов: 42
Ответов: 385
 Web-сайт: vt-dbnz.narod.ru
 Профиль | | #14
Добавлено: 02.11.05 01:27
Да. Здесь, похоже, будет легче написать парсилку содержимого реестра, с учетом всяких там dde. И изучать все тонкости.

Ну, можно, конечно, пойти тупо.
Делаем список окон до заветного вызова... и после него. Сравниваем, получаем ответ - какие окна появились. Оттуда можно даже PID вытащить.
Конечно, это не претендует на надежное решение, просто как вариант. Я знаю, что пока ShellExecute выполняется, могут появится окна, не имеющие к ней никакого отношения (мало ли, че там еще юзверь делает), которые тоже поймаются. Или могут быть такие, которые появляются далеко не сразу...

Ответить

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



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #15 Добавлено: 02.11.05 12:44
Тут можно фильтрануть процессы по имени экзешника и ID Parent процесса, но если юзер запускает два аналогичных процесса - уже проблемы :)

Ответить

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

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



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