Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.89
kravam
быдлокодер
1701 / 888 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
#1

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

16.07.2011, 20:56. Просмотров 2458. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.07.2011, 20:56
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему? (C++):

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

Родительский и дочерний процесс - C++
Для начала код. ProcessA#include &lt;windows.h&gt; #include &lt;iostream&gt; #include &lt;stdio.h&gt; int main() { STARTUPINFO si;...

Передать параметр в дочерний процесс через execl() - C++
Немного не по теме .. но может кто знает , как это сделать Создаю дочерний процесс . В него нужно передать число , которое вводится в...

Inject процесса в процесс win7 - C++
Добрый день форумчане! Вот уже как месяц бьюсь на этой проблемой и никто не в состоянии мне помочь! Обыскал кучу сайтов и нашел интересные!...

Загрузить процесс из другого процесса - C++
Штурм google ничего не дал. Но я помню что что то было такое в книге Рихтера. Пока ищу книгу и нужную страницу, решил оформить все таки...

Процесс А инициализирует массив случайными значениями и записывает их в файл, а затем запускает процесс Б - C++
В универ нужно сделать лабу по выше указанной теме. Мне не нужно чтобы за меня делали - нужен просто совет. Для начала: Задание:...

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

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

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

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

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

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

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

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

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

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

P.S. Насколько я помню, DuplicateHandle выдает другой хэндл даже при полном совпадении прав доступа. Скорее всего, OpenProcess реализует похожую стратегию.
P.P.S. В своих знаниях по глубинному устройству Windows я не совсем уверен, так что если есть спецы, поправьте меня
0
kravam
быдлокодер
1701 / 888 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
17.07.2011, 11:25  [ТС] #8
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
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 11:53 #9
Очень странно, что TerminateProcess на первом хэндле не сработал.
А что GetLastError говорит?
0
kravam
быдлокодер
1701 / 888 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
17.07.2011, 12:23  [ТС] #10
Я не умею ей пользоваться, в 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
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 12:31 #11
Ошибка 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
быдлокодер
1701 / 888 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
17.07.2011, 13:24  [ТС] #12
Всё получилось, а вот Ваш код я подогнал под свой, то есть просто не прерываю цикл принудительно. И тоже родительский процесс благополучно уничтожается.

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
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
17.07.2011, 14:37 #13
Я скидывал принудительно ошибку, которую повесит Process32Next, когда больше не осталось процессов, чтобы получить именно ошибку от TerminateProcess. Странно, что у Вас эта ошибка появилась раньше.
1
kravam
быдлокодер
1701 / 888 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
17.07.2011, 17:43  [ТС] #14
Будем считать вопрос условно-решённым, спасибо большое.
0
17.07.2011, 17:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.07.2011, 17:43
Привет! Вот еще темы с ответами:

Что будет,если закрыть хэндл с открытым процессом,потоком? Или это только информация? - C++
Что будет,если закрыть хэндл с открытым процессом,потоком? Или это только информация?

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

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

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


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru