Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/55: Рейтинг темы: голосов - 55, средняя оценка - 4.55
 Аватар для Nalik
176 / 124 / 49
Регистрация: 30.11.2012
Сообщений: 1,330

Узнать дескриптор окна запускаемой программы

30.09.2015, 10:55. Показов 11601. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Запускаю программу таким образом:
C#
1
2
3
4
5
6
7
            ProcessStartInfo startInfo = new ProcessStartInfo(file_directory); //Путь
            startInfo.WorkingDirectory = working_directory; //Рабочая папка
            startInfo.Arguments = arguments; //Аргументы
            try
            {
                Process.Start(startInfo); //Запуск
            } catch (Exception)
как можно узнать дескриптор главного ОКНА запускаемой программы?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.09.2015, 10:55
Ответы с готовыми решениями:

Узнать дескриптор окна
Всем привет. В общем у меня такая проблема: запускается приложение => появляется главное окно (1-е) и сразу же появляется окно ввода логина...

Как узнать дескриптор окна приложения?
Здравствуйте, в user32.dll есть такая функция: SetForegroundWindow(hWnd) Понадобилось мне вывести окно наверх экрана. Дескриптор...

Как получить снимок рабочей области окна программы зная его дескриптор?
Как получить снимок рабочей области окна программы зная его дескриптор?

11
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.09.2015, 12:13
Nalik, как насчет process.MainWindowHandle ?
0
 Аватар для Nalik
176 / 124 / 49
Регистрация: 30.11.2012
Сообщений: 1,330
30.09.2015, 12:35  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Nalik, как насчет process.MainWindowHandle ?
Не катит, уже пробовал. Кстати я так понимаю process.MainWindowHandle возвращает именно заголовок процесса, а не окна?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.09.2015, 12:42
google translate "Main Window Handle" -> Дескриптор Главного Окна - не?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
30.09.2015, 13:06
У запускаемой программы может быть несколько окон, и не всегда именно то окно которое вы хотите является главным. Если же окно одно, то process.MainWindowHandle именно то что вам нужно.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.09.2015, 13:19
Nalik, выше верно сказали. Я в своё время тоже намучился, но получил рабочее решение.
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
54
class ExeLockFounder
{
    const uint WM_SETTEXT = 0x000C;
    delegate bool EnumDelegate(IntPtr hWnd, IntPtr lParam);
 
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
 
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow);
 
    [DllImport("user32.dll")]
    static extern bool EnumThreadWindows(int dwThreadId, EnumDelegate lpfn, IntPtr lParam);
 
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);
 
    private static IntPtr GetWindowByClassName(IEnumerable<IntPtr> windows, string className)
    {
        foreach (var window in windows)
        {
            var sb = new StringBuilder(256);
            GetClassName(window, sb, sb.Capacity);
            if (sb.ToString() == className)
                return window;
        }
        return IntPtr.Zero;
    }
 
    static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process)
    {
        var handles = new List<IntPtr>();
        foreach (ProcessThread thread in process.Threads)
            EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
        return handles;
    }
 
    private readonly IntPtr _editHandle;
 
    public ExeLockFounder()
    {
        var processes = Process.GetProcessesByName("Setup");
        var proc = Array.Find(processes, x => string.Equals(x.MainWindowTitle, "ExeLock", StringComparison.OrdinalIgnoreCase));
 
        var windows = EnumerateProcessWindowHandles(proc);
        var hWnd = GetWindowByClassName(windows, "TFormPassDialog");
        _editHandle = FindWindowEx(hWnd, IntPtr.Zero, "TEdit", null);
    }
 
    public void SendText(string message)
    {
        SendMessage(_editHandle, WM_SETTEXT, IntPtr.Zero, message);
    }
}
Тут я находил окно типа "TFormPassDialog" (нужная мне форма, когда как главное окно имело тип ExeLock), принадлежащее процессу "Setup". После чего находил там нужный мне TEdit и вбивал в него некоторый текст. Немного расширив, можно написать такой хелпер:
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
public static class WinApi
{
    delegate bool EnumDelegate(IntPtr hWnd, IntPtr lParam);
 
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
 
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow);
 
    [DllImport("user32.dll")]
    static extern bool EnumThreadWindows(int dwThreadId, EnumDelegate lpfn, IntPtr lParam);
 
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);
 
    private static IntPtr GetWindowByClassName(IEnumerable<IntPtr> windows, string className)
    {
        foreach (var window in windows)
        {
            var sb = new StringBuilder(256);
            GetClassName(window, sb, sb.Capacity);
            if (sb.ToString() == className)
                return window;
        }
        return IntPtr.Zero;
    }
 
    public static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process)
    {
        var handles = new List<IntPtr>();
        foreach (ProcessThread thread in process.Threads)
            EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);
        return handles;
    }
 
    public static IntPtr GetWindowByClassName(Process proc, string className)
    {
        var windows = EnumerateProcessWindowHandles(proc);
        var hWnd = GetWindowByClassName(windows, className);
        return hWnd;
    }
 
    public static IntPtr GetObjectByClassName(Process proc, string windowClassName, string className)
    {
        var window = GetWindowByClassName(proc, windowClassName);
        return FindWindowEx(window, IntPtr.Zero, className, null);
    }
}
1
 Аватар для Nalik
176 / 124 / 49
Регистрация: 30.11.2012
Сообщений: 1,330
30.09.2015, 13:34  [ТС]
Хорошо. Проведем маленький эксперимент.
Будем искать дескриптор окна на прямую, зная заголовок.
Будем искать дескриптор окна через перечисления всех окон используя process.MainWindowHandle.

Вот код:

C#
1
2
3
4
5
6
7
8
9
10
11
Process[] processlist = Process.GetProcesses();
 
            foreach (Process process in processlist)
            {
                if ((process.MainWindowHandle) != IntPtr.Zero)
                {
                    IntPtr Handle = FindWindow(null, "PR Automizer - Поток " + number_potok); //находим окно
                    MessageBox.Show(Handle.ToString()); //Дескриптор 136060 найден
                    MessageBox.Show("ID: " + process.Id + "\nЗаголовок: " + process.MainWindowTitle + "\nДескриптор: " + process.MainWindowHandle); //Дескриптор 
                }
            }

В итоге:
1) Мы имеем дескриптор который узнали на прямую: 136060
2) process.MainWindowHandle вообще отказался искать это окно, такой дескриптор не разу не появился. Единственное было упоминание о нём указанное на картинке 2 во вложении, заголовок progh8 действительно имеет отношение к этой программе, но как видно из скрина, дескриптор не верный.
Изображения
  
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.09.2015, 13:43
Nalik, экзешник скиньте.
0
 Аватар для Nalik
176 / 124 / 49
Регистрация: 30.11.2012
Сообщений: 1,330
30.09.2015, 13:55  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Я в своё время тоже намучился, но получил рабочее решение.
Спасибо, буду детально разбираться в вашем решении чуть позже, сейчас не успею уже)
Единственное, мне кажется как-то слишком много кода и на вскидку глядя на код оно не удовлетворяет моим желаниям)
Я через EnumWindows реализовал поиск нужного мне окна, получаю его дескриптор.
Но хотелось бы не искать окно из всех существующих, а именно получать окно от запускаемой программы. Т.е. я себе это представлял так:
1. Запускаю программу -> Жду пока она загрузится -> Она загрузилась и сразу же отдала мне свой hwnd.

Т.е. я хотел бы чтобы была именно неразрывная цепочка.

Добавлено через 4 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
Nalik, экзешник скиньте.
К сожаления, я не могу этого сделать.
P.s. Данный код нормально работает с блокнотом. Но суть в другом, я хотел не перебирать все окна в системе. А привязаться именно к запускаемому файлу.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.09.2015, 14:09
Nalik, вы параметр Process видет? Он перебирает окна, который создал некоторый процесс и ищет там это нужное окно. Проблема в том, что ВЫ считаете главным окном и что система считает - совсем не одно и то же. За примером далеко ходить не надо:
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
using System;
using System.Windows.Forms;
 
namespace WindowsFormsApplication3
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
 
 
            var form1 = new Form
            {
                Text = "Я главная форма!"
            };
 
            var form2 = new Form
            {
                Text = "А я не главная форма, но пользователь меня видит!"
            };
 
            form1.Activated += (sender, args) =>
            {
                form1.Hide();
                form2.Show();
            };
 
            Application.Run(form1);
        }
    }
}
0
 Аватар для Nalik
176 / 124 / 49
Регистрация: 30.11.2012
Сообщений: 1,330
30.09.2015, 14:45  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Проблема в том, что ВЫ считаете главным окном и что система считает - совсем не одно и то же. За примером далеко ходить не надо:
Сразу прошения за внешний вид скринов которые прикладываю, сильно не шифруются, но афишировать не могу..
Я вас понял, но думаю дело не в этом. Других форм там нету. А вот на счет того, что система считает главным окном, очень может быть. Вот окно которое я ищу, может это что нибудь прояснит.

Так же интересная особенность, которая меня смущает. При наведении мышкой на миниатюрку программы на панеле задач - заголовок один. А в самой программе заголовок другой. Обычно бывают одинаковые.


Цитата Сообщение от Psilon Посмотреть сообщение
Nalik, вы параметр Process видет? Он перебирает окна, который создал некоторый процесс и ищет там это нужное окно.
Некоторый процесс это интересно какой? Потому что блокнот который я открывал ручками он нашел, не смотря на то что он был открыт не из программы.
Миниатюры
Узнать дескриптор окна запускаемой программы   Узнать дескриптор окна запускаемой программы   Узнать дескриптор окна запускаемой программы  

Узнать дескриптор окна запускаемой программы   Узнать дескриптор окна запускаемой программы  
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
30.09.2015, 14:51
Nalik, вот кстати у человека пример, в котором главное окно не главное окно
Как вести пароль в программе exe автоматически
Можете посмотреть на него Spy++. Там главное окно - ExeLock, а окно, которое пользователь считает главным - Exe Lock (с пробелом). Можете посмотреть на их структуру, довольно забавно.

Дочерние окна не будут "вложенными" в Spy++, это тоже надо понимать.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.09.2015, 14:51
Помогаю со студенческими работами здесь

Перерисовка окна другого процесса через дескриптор этого окна
Приветствую всех. Может кто-то знает, как перерисовать окно другого процесса через дескриптор (IntPtr) этого окна. Может апишная функция...

Можно ли убрать рамки у запускаемой программы?
Здравствуйте, собственно вопрос. Запускаю сторонний exe как дочернее окно в форме. И крайне не нравится, что у открывающегося приложения...

Узнать дескриптор обьекта типа SerialPort
Здраствуйте, в программе необходимо получить структуру с настройками последовательного порта DCB. Пока нашёл одно решение - импортировать...

С помощью WinApi функции найти дескриптор окна
static extern IntPtr FindWindow ( string lpClassName, string lpWindowName ); static extern int gwt ( ...

Получить дескриптор окна стороннего приложения и контекстного меню
Здравствуйте. Подскажите пожалуйста. Как можно словить дескриптор выскакивающего окна? в списке Spy++ этого окна нет, т.к. оно...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
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