Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Найти окно по классу, в терминальной сессии 
:(
    Опции темы
Danger
Дата 23.7.2009, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



Привет всем,
Вобщем, есть терминальный сервер, удаленные пользователи через терминал запускают определенную программу (уникальный класс окна, создаваемый программой, знаю). Нужно "пробежаться" по всем сессиям, и проверить наличие в них окна с определенным классом.

Вот здесь уже обсуждалось: http://www.delphimaster.ru/cgi-bin/forum.p...9955786&n=5 попробовал, как описано - нифига не работает. Непонятно, как получить Desktop терминальной сессии ( WTSEnumerateSessions() перечисляет лишь имена сессий, но не windows stations). Максимум, могу получить список процессов терминальной сессии - но по ним же я не могу получить список окон, созданных этими процессами?

Кто знает, посоветуйте, пожалста..

PM WWW ICQ Jabber   Вверх
kami
Дата 23.7.2009, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



WTSEnumerateSessions возвращает массив WTS_SESSION_INFO, один из параметров которой - pWinStationName.

Пройдя по массиву, найдя нужную терминальную сессию и WinSta, проходим по EnumDesktops, находим нужный и EnumDesktopWindows.

Добавлено через 8 минут и 36 секунд
мда...
поторопился немного. Для того, чтобы перечислить десктопы нужно открыть winSta, а в OpenWindowStation не учитывается сессия...
PM MAIL WWW   Вверх
kami
Дата 23.7.2009, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Danger @  23.7.2009,  13:12 Найти цитируемый пост)
Максимум, могу получить список процессов терминальной сессии - но по ним же я не могу получить список окон

а если так:
WTSEnumerateProcesses>CreateToolhelp32Snapshot & Thread32First|Next>EnumThreadWindows .....
PM MAIL WWW   Вверх
Danger
Дата 24.7.2009, 05:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



Цитата(kami @ 23.7.2009,  17:59)
Для того, чтобы перечислить десктопы нужно открыть winSta, а в OpenWindowStation не учитывается сессия...

Кстати, в процессе я так и не понял, что там с windows station в терминальных сессиях. То ли, используется текущая (консольная) window station ('WInSta0'), либо для всех терминальных сессий window station называется всегда одинаково (упомянутый 'WinSta0').

Вообще, существует ли способ перечислить не сессии, а window station терминальных сессий?

Насчет 
Цитата(kami @ 23.7.2009,  17:59)
WTSEnumerateProcesses>CreateToolhelp32Snapshot & Thread32First|Next>EnumThreadWindows .....

Неясно, как связать данные, получаемые через WTSEnumerateProcesses() и CreateToolhelp32Snapshot().
Точнее, непонятно зачем нужна CreateToolhelp32Snapshot(), если WTSEnumerateProcesses() и так вернет список терминальных процессов? Может, CreateToolhelp32Snapshot() не нужен, или я что-то не понимаю?


Это сообщение отредактировал(а) Danger - 24.7.2009, 06:03
PM WWW ICQ Jabber   Вверх
kami
Дата 24.7.2009, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Danger @  24.7.2009,  05:21 Найти цитируемый пост)
 что там с windows station в терминальных сессиях

afaik, каждой терминальной сессии соответствует одна (СВОЯ) winSta. А вот название ее может отличаться:
Цитата

pWinStationName

Pointer to a null-terminated string that contains the WinStation name of this session. The WinStation name is a name that Windows associates with the session, for example, "services", "console", or "RDP-Tcp#0".



Цитата(Danger @  24.7.2009,  05:21 Найти цитируемый пост)
непонятно зачем нужна CreateToolhelp32Snapshot(), если WTSEnumerateProcesses() и так вернет список терминальных процессов? Может, CreateToolhelp32Snapshot() не нужен, или я что-то не понимаю?

Наоборот smile это я опять недосмотрел, что в CreateToolhelp32Snapshot при указании TH32CS_SNAPTHREAD будут перечисляться все потоки в системе, а не потоки текущего процесса.

Цитата(Danger @  24.7.2009,  05:21 Найти цитируемый пост)
WTSEnumerateProcesses() и так вернет список терминальных процессов?

ну да, но окна-то вроде можно перечислить только для потока, а не для процесса (EnumThreadWindows), соответственно - просто список процессов ничего не даст...
PM MAIL WWW   Вверх
Danger
Дата 24.7.2009, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



так что же делать?  smile я запутался, честно.
PM WWW ICQ Jabber   Вверх
kami
Дата 24.7.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



попробуй так:
CreateToolhelp32Snapshot>Thread32First|Next>EnumThreadWindows>GetClassName.

Если нужно потом найти, в какой сессии это окно находится, то:
в Thread32First|Next>THREADENTRY32 есть параметр th32OwnerProcessID.
ProcessIDToSessionID, а зная SessionID можно получать о ней информацию из WTSQuerySessionInformation...
PM MAIL WWW   Вверх
Danger
Дата 24.7.2009, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



Цитата(kami @ 24.7.2009,  12:52)
попробуй так:
CreateToolhelp32Snapshot>Thread32First|Next>EnumThreadWindows>GetClassName.

Такое ощущение, что в слепок попадают только потоки, принадлежащие текущей window station.
Ни одного потока с процессов другого терминального пользователя..

Код

.....
//-----------------------------------------------------
function EnumThreadWndProc( Wnd: HWND; Param: LParam ): Boolean; stdcall;
var
 dwProcessId: DWord; strOwner: string;
 timeCreate: PFileTime;

begin
  Result:= true;  // we're enumerate all the thread windows

  ZeroMemory( @strWndClass, dwBufferSize );
  GetClassName( Wnd, strWndClass, dwBufferSize - 1 );

    dwProcessId:= PTHREADENTRY32( Param )^.th32OwnerProcessID;
    New( timeCreate );
    try
      if ( GetProcessParams( dwProcessId, strOwner, timeCreate ) ) then
      begin
        // using OEM codepage
        CharToOem( PChar( strOwner), PChar( strOwner ) );
        WriteLn( ' | ', dwProcessId, #9, '| ', FileTimeToStr( timeCreate ), #9, '| ', strOwner, #9, '|' );
      end;
     finally
       Dispose( timeCreate );
     end;
end;

//-----------------------------------------------------
begin
 .....

 // take a snapshot of all running threads
 hThreadSnap:= CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
 if ( hThreadSnap > 0 ) then
 begin

   te32.dwSize:= SizeOf( THREADENTRY32 );
   if ( Thread32First( hThreadSnap, te32 ) ) then
   begin
     EnumThreadWindows( te32.th32ThreadID, @EnumThreadWndProc, Integer( @te32 ) );
     // now walk the thread list of the system
     while ( Thread32Next( hThreadSnap, te32 ) ) do
      EnumThreadWindows( te32.th32ThreadID, @EnumThreadWndProc, Integer( @te32 ) );
   end;

   CloseHandle( hThreadSnap );
 end; // 'if ( hThreadSnap > 0 ) then '

//-----------------------------------------------------

GetProcessParams() - простейшая функция-"обёртка", возвращает некоторые параметры процесса..
PM WWW ICQ Jabber   Вверх
kami
Дата 25.7.2009, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Так погляжу, на "соседнем" форуме посоветовали то, о чем я думал, но не хотел говорить - может есть менее обходной путь, чем запуск дополнительного процесса в каждой терминальной сессии...
Но мнение Eraser -а в таких вопросах можно считать непререкаемым.
Посему - уточняющие вопросы: версия ОС, в которой нужно найти нужное окно в терминальной сессии?
PM MAIL WWW   Вверх
Danger
Дата 26.7.2009, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



Цитата(kami @ 25.7.2009,  22:32)
Так погляжу, на "соседнем" форуме посоветовали то, о чем я думал, но не хотел говорить - может есть менее обходной путь, чем запуск дополнительного процесса в каждой терминальной сессии...

А что, если отталкиваться от списка процессов, возвращаемых WTSEnumerateProcesses() ?
Т.е. получить список процессов, потом для каждого из них потоки, и в них искать окно? (без создания снимков).

Цитата(kami @ 25.7.2009,  22:32)

Посему - уточняющие вопросы: версия ОС, в которой нужно найти нужное окно в терминальной сессии?

MS Windows 2003 VLK Russian (R2), 32bit.
PM WWW ICQ Jabber   Вверх
kami
Дата 26.7.2009, 03:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
получить список процессов, потом для каждого из них потоки, и в них искать окно?

Не нашел функцию перечисления потоков по известному процессу. :( Покажете, как?

Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
MS Windows 2003

Ага, значит предложенное Eraser-ом более чем возможно.


Это сообщение отредактировал(а) kami - 26.7.2009, 03:34
PM MAIL WWW   Вверх
Danger
Дата 26.7.2009, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



Цитата(kami @ 26.7.2009,  03:34)
Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
получить список процессов, потом для каждого из них потоки, и в них искать окно?

Не нашел функцию перечисления потоков по известному процессу. :(
Я имею в виду, сделать снимок CreateToolhelp32Snapshot() по ProcessID терминального процесса, и перечислить потоки по Thread32First() / Thread32Next(). Хотя, боюсь, получится то же самое (но попробовать стоит).

Цитата(kami @ 26.7.2009,  03:34)
Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)

Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
MS Windows 2003

Ага, значит предложенное Eraser-ом более чем возможно.
Проблема в том, что мне придется внедрять свой процесс в сессию каждого терминального пользователя, либо для каждого пользователя добавлять в автозагрузку прогу, постоянно висящую в памяти. И все это только для того, чтоб я когда-то мог узнать -  есть ли у пользователя на десктопе данное окно.

PM WWW ICQ Jabber   Вверх
kami
Дата 26.7.2009, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Danger @  26.7.2009,  10:58 Найти цитируемый пост)
делать снимок CreateToolhelp32Snapshot() по ProcessID терминального процесса, и перечислить потоки по Thread32First() / Thread32Next()

Цитата(kami @  24.7.2009,  12:33 Найти цитируемый пост)
 в CreateToolhelp32Snapshot при указании TH32CS_SNAPTHREAD будут перечисляться все потоки в системе, а не потоки текущего процесса.


PM MAIL WWW   Вверх
Danger
Дата 26.7.2009, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 20.9.2006

Репутация: нет
Всего: нет



Что характерно: запускаю Process Explorer от Sysinternals (в терминальной сессии), и он мне исправно перечисляет процессы других терминальных пользователей и потоки в них.
Да банально: диспетчер задач отображает все процессы, всех пользователей (с указанием имени пользователя и параметров процесса). Как-то же он это делает?

Это сообщение отредактировал(а) Danger - 26.7.2009, 18:25
PM WWW ICQ Jabber   Вверх
kami
Дата 26.7.2009, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Danger @  26.7.2009,  15:06 Найти цитируемый пост)
запускаю Process Explorer от Sysinternals (в терминальной сессии), и он мне исправно перечисляет процессы других терминальных пользователей и потоки в них.

afaik, он использует свой драйвер, устанавливаемый на время его работы (драйвер находится в его ресурсах). Иначе многие из его возможностей (к примеру - закрытие любого хендла) из user-mode выглядят нереально.


Цитата(Danger @  26.7.2009,  15:06 Найти цитируемый пост)
диспетчер задач отображает все процессы, всех пользователей (с указанием имени пользователя и параметров процесса). Как-то же он это делает?

Да перечислить процессы и получить их параметры не так и сложно. А вот перечислить потоки процесса и окна потоков - с учетом 
Цитата(Danger @  24.7.2009,  20:16 Найти цитируемый пост)
Такое ощущение, что в слепок попадают только потоки, принадлежащие текущей window station.

не вижу решения, кроме предложенного eraser-ом.

P.S. А почему именно окно?
Нельзя будет обойтись запущен/не запущен процесс?
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0985 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.