Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/19: Рейтинг темы: голосов - 19, средняя оценка - 4.63
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698

Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?

16.07.2011, 20:56. Показов 4092. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья! Вот код A.exe, суть которого просто стать родительским для B.exe и висеть в системе.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <windows.h>
 
int main() {
 STARTUPINFO si;
 PROCESS_INFORMATION pi;
 ZeroMemory(&si,sizeof(STARTUPINFO) );
 
 if (CreateProcess ("B.exe", 0, 0, 0, 0, 0, 0, 0, &si, &pi)) { 
  CloseHandle( pi.hProcess );
  CloseHandle( pi.hThread );
 }
 
 
 else {
  printf ("protsess ne sozdan\n");
 }
 
 while (1);
 
// system ("pause");
 return 0;
}

Так, а вот код B.exe,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h> 
#include <Windows.h> 
#include <Winnt.h> 
#include <tlhelp32.h>
 
int main () {
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  
  //Это будет ID текущего процеса
  DWORD handle_B= (DWORD)GetCurrentProcessId();  
  
  //Это находим дескриптор снимка процессов
  HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
  if (hProcessSnap == INVALID_HANDLE_VALUE)
   return false;
  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof(PROCESSENTRY32);
 
  //и пошли циклом пробегаться по этим процессам, остановимся на двух, на текущем и родительском
  //Выводимые данные, напомню, берутся из структуры pe32
  while (Process32Next(hProcessSnap, &pe32)) {
   
   //Ага, здесь мы споткнулись о текущий процесс 
   if (handle_B== pe32.th32ProcessID) {
    printf ("тут должно быть имя B.exe  %s  \n", pe32.szExeFile);
    printf ("Так, а тут ID родительского процесса, то есть ID процесса A.exe=   %x  \n", pe32.th32ParentProcessID);
    getchar ();
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ParentProcessID);
   
    //И вывели хэндл его родительского процесса, который A.exe
    printf ("А тут собственно хэндл процесса A.exe!   %x\n", handle);
    getchar ();   
   }
 
   //Так, а здесь мы споткнулись о родительский процесс
   if (!strcmp ("A.exe", pe32.szExeFile)) {
    printf ("ЗДесь должно быть имя процесса A.exe   %s  \n", pe32.szExeFile);
    printf ("Зесь его ID  %x  \n", pe32.th32ProcessID);
    getchar ();
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ProcessID);
    
    //И опять выводим его хэендл. Так вот, в выводе хэндлы A.exe разнятся!
    printf ("А тут его хэндл, комментарии излишни!   %x\n", handle);
    getchar ();   
   }
  }  
 
 
  CloseHandle(hProcessSnap);
  getchar ();
  return 0;
 }


его роль: перебрать все процессы оси.

Найти себя-> найти хэндл родительского процесса и вывести его
и
Найти хэндл процесса A.exe-> вывести его

Эти два пунта могут меняться местами в зависимости от того, какой процесс будет найден первым.
Но я надеюсь никто не сомневается в том, что выводимые хэндлы должны быть одинаковы в обоих случаях? А зря.
Смотрим вывод.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.07.2011, 20:56
Ответы с готовыми решениями:

Передача аргументов из родительского в дочерний процесс
Привет всем! Подскажите, пожалуйста! как передать аргументы argv функции main() из родительского в дочерний процесс?

Родительский и дочерний процесс: почему запуск начинается сразу с дочернего процесса?
Родительский процесс должен считать содержимое текстового файла и передать его дочернему процессу. Дочерний процесс в полученном тексте...

Чтение памяти другого процесса по таймеру: нужно ли закрывать хэндл процесса?
В моём варианте работает так: По таймеру (0,1 сек) определяю ID процесса по ехе-шнику, получаю хэндл процесса(открываю процесс) ...

13
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
16.07.2011, 21:03  [ТС]
Вот вывод
Миниатюры
Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?  
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
16.07.2011, 22:20
Так хэндл и не обязан быть одинаковым.
Каждый процесс имеет свою собственную таблицу хэндлов, и какой хэндл будет ссылаться на тот или иной объект, решает уже система.
А вот ID какого-либо процесса является величиной постоянной, какой бы другой процесс его не запрашивал, именно поэтому для получения хэндла чужого процесса используют ID

P.S. Грубо говоря, хэндл - это указатель на некий объект в глубине системы. А указатель работает в адресном пространстве только своего процесса. Для другого процесса указатель на ту же область памяти может иметь совсем другое значение, благодаря механизму трансляции адресов. Так что все штатно.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
17.07.2011, 01:21  [ТС]
Нет, нештатно. Я говорю:
вот процесс B получает хэндл процесса A, этот хэндл равен x
И
опять вот процесс B получает хэндл процесса A, этот хэндл равен y

Он получает одну и ту же величину, только по-разному. Один и тот же указатель ё. И этот указатель непостоянен.
0
Заблокирован
17.07.2011, 02:54
Цитата Сообщение от kravam Посмотреть сообщение
Нет, нештатно. Я говорю:
вот процесс B получает хэндл процесса A, этот хэндл равен x
И
опять вот процесс B получает хэндл процесса A, этот хэндл равен y

Он получает одну и ту же величину, только по-разному. Один и тот же указатель ё. И этот указатель непостоянен.
Понимаешь в чем тонкость.... ваш хэндл на самом деле ни что иное, как:

typedef void *HANDLE; //всего лишь всевдоним обычного указателя на войд

Почему два разных процесса указывают казалось бы на одно и тоже место в памяти, но при этом адреса разные?

Начните читать с 22# сообщения по этой ссылке.
Указатели
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
17.07.2011, 10:10  [ТС]
Я прочту, конечно, но... Мне кажется, я представляю себе, что такое хэндл.
В процессе есть таблица хэндлов, а у Рихтера она называется таблица описаталей.
И там есть разные всякие хэндлы. И очередной хэндл это
"индекс в таблице описателей, принадлежащей процессу"
И это индексы разны. Вот что странно.
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 10:55
Сорри, не очень внимательно глянул исходник. Но все равно все штатно.

Один и тот же объект может быть открыт под разными хэндлами даже в одном процессе.
Насколько я понимаю внутреннее устройство Windows, обращение к объекту идет следующим образом:

хэндл -> объект-описатель -> собственно объект в памяти ядра

Так вот, объект в памяти ядра у нас один-единственный, и ему соответствует уникальный ID. А вот объектов-описателей может быть много. Причин для этого вижу две, и обе связаны с обязанностями объекта-описателя:
- у разных описателей могут быть разные права доступа к объекту ядра, хотя бы поэтому их может быть несколько
- при разрушении описателя, система подсчитывает количество оставшихся описателей, и грохает объект ядра (к процессу, правда, это не относится, т.к. на него, скорее всего, есть еще как минимум одна ссылка внутри самого ядра до окончания работы)

P.S. Насколько я помню, DuplicateHandle выдает другой хэндл даже при полном совпадении прав доступа. Скорее всего, OpenProcess реализует похожую стратегию.
P.P.S. В своих знаниях по глубинному устройству Windows я не совсем уверен, так что если есть спецы, поправьте меня
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
17.07.2011, 11:25  [ТС]
soft.creator, мне это как-то поможет?
Я вызываю хэндл двумя способами (хотя язык не поворачивается называть 2 вызова одной и той же функции с одними и теми же параметрами как 2 способа). Но по крайне ймере в исходнике они разделены.

Так вот, второй способ- истиный. Я это определил так:
C++
1
2
3
4
5
6
7
8
9
   if (!strcmp ("A.exe", pe32.szExeFile)) {
    printf ("Çåñü åãî ID  %x  \n", pe32.th32ProcessID);
    getchar ();
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ProcessID);
    
    //ЕСли этот способ истиный, то хэндл правильный и родительский процесс закроется.
    TerminateProcess (handle, 0);
    getchar ();   
   }
И родительский процесс закрывается. Так, а если я использую другой хэндл, то не закрывается.
А у меня стоит задача, чтобы закрыть родительский процесс не исходя из его имени, которое дочерний просто не знает- то есть дочерний процесс должен закрыть родительский, а исходя из его ID (первый способ)
А он не работает
........................................ .....................
В ссыли добил пост номер 45

Добавлено через 9 минут
Цитата Сообщение от soft.creator Посмотреть сообщение
Скорее всего, OpenProcess реализует похожую стратегию.
Так-то мне всё равно. Если можешь выдать нормальный хэндл, выдай, пусть он хоть от вызова к вызову меняется. Не можешь выдать- выдай ноль. Но выдывать ненулевой неправильный хэндл, при чём какой какой красивый:28 не (12345678 и не 877654321) это у меня слов нет.
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 11:53
Очень странно, что TerminateProcess на первом хэндле не сработал.
А что GetLastError говорит?
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
17.07.2011, 12:23  [ТС]
Я не умею ей пользоваться, в MSND примеров нет. Вот так на свой страх и риск написал:
C++
1
2
3
4
    HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ParentProcessID);
    //HANDLE handle= OpenProcess (PROCESS_TERMINATE, true, pe32.szExeFile);
    DWORD mistake= GetLastError ();
    printf ("mistake= %d\n", mistake);
Выводит 2

Добавлено через 8 минут
А в MSND прочёл
The system cannot find the file specified.


Это что система не может найти, какой-то файл? Что-то не то.
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 12:31
Ошибка 2 - объект не найден. Странная ошибка в этом контексте.
Попробуйте вот что:
C
1
2
3
4
5
6
7
8
9
10
11
    HANDLE handle;
    while (Process32Next(...)) {
        if (...) {
            handle = OpenProcess(..., pe32.th32ParentProcessID);
            break;
        }
    }
    printf("Handle = %x, error before = %d\n", handle, GetLastError());
    SetLastError(0);
    TerminateProcess(handle, 0);
    printf("Error after = %d\n", GetLastError());
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
17.07.2011, 13:24  [ТС]
Всё получилось, а вот Ваш код я подогнал под свой, то есть просто не прерываю цикл принудительно. И тоже родительский процесс благополучно уничтожается.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  while (Process32Next(hProcessSnap, &pe32)) {
   //Ага, здесь мы споткнулись о текущий процесс 
   printf ("\nЗдесь ID найденного процесса  %x  \n", pe32.th32ProcessID);
   printf ("ID Текущего процесса  %x  \n", handle_B);
   getchar ();
   if (handle_B== pe32.th32ProcessID) {
    handle= OpenProcess (PROCESS_TERMINATE, true, pe32.th32ParentProcessID);
 
    printf("Handle = %x, error before = %d\n", handle, GetLastError());
    SetLastError(0);
    TerminateProcess(handle, 0);
    printf("Error after = %d\n", GetLastError());    
    
    //Тут  можно поставить break;    
 
   }
  }
...Так это что мы делаем? Просто напросто принудительно скидываем ошибку (мы ведь не смогли найти ей по факту вот и решили скинуть в ноль, так?) И дальше код нормально работает.

Вопрос остался: почему всё-таки возвращалась ошибка 2?
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 14:37
Я скидывал принудительно ошибку, которую повесит Process32Next, когда больше не осталось процессов, чтобы получить именно ошибку от TerminateProcess. Странно, что у Вас эта ошибка появилась раньше.
1
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
17.07.2011, 17:43  [ТС]
Будем считать вопрос условно-решённым, спасибо большое.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.07.2011, 17:43
Помогаю со студенческими работами здесь

Хэндл процесса по названию
Всем Доброго Времени Суток! Нигде не могу найти информацию по этому поводу. Я запустил программу через ShellExecute и нужно поймать хэндл...

Запущен ли процесс? или Завершен ли дочерний процесс моей программы?
Моя программа выполняет execute('cmd', '/C ...'). На момент execute-а других экземпляров cmd.exe нет. Мне хочется узнать, когда окошко cmd...

Родительский и дочерний процесс: процесс не переходит обратно к родителю
Здравствуйте знаю что тема уже была, но все же! создаю элементарную программу, пока просто 1 дочерний процесс, но после запуска родителя...

Найти окно, если известен ID и хэндл процесса
Можно ли найти окно, принадлежащее определённому процессу (хэндл и ID процесса известны)?

Получить ID процесса если известно его хэндл, название окна или название процесса
а как получить ID процесса если известно его хэндл, название окна или название процесса?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru