Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 18.08.2017
Сообщений: 16
1

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

21.06.2019, 23:41. Просмотров 1772. Ответов 7
Метки нет (Все метки)

Привет всем! Я работаю на лазерном комплексе под управлением китайской софтины CypCut Laser Cutting System 6.3.731.5.
Это обычная программа для виндовс (в моем случае это семёрка). Программа бесплатная, можно скачать где угодно.
По ходу работы программа пишет лог событий/команд/ошибок и прочего.
Скриншот:
Как считать данные из стороннего приложения?

У меня возникла идея сделать небольшое приложение на С# которое будет считывать текущий лог и подавать звуковой сигнал на колонки. Например, если станок закончил работу или в процессе появилась какая-нибудь ошибка.
Короче вопрос такой, как с помощью C# считать информацию из текстового поля сторонней софтины?
Заранее спасибо!
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.06.2019, 23:41
Ответы с готовыми решениями:

Считать текст из окна стороннего приложения
Здравствуйте. Скажите пожалуйста как считать текст из таких окон как прикреплены к сообщению?????

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

Как проверить открыто ли окно стороннего приложения?
Я не знаю как написать программу, которая бы проверяла (т.е. if окно в фокусе then), помогите, мне...

Как выбрать пункт в ListBoxe стороннего приложения?
Запускаю сторонее приложение Process fps = new Process(); ...

7
281 / 200 / 72
Регистрация: 17.08.2014
Сообщений: 787
22.06.2019, 21:35 2
Цитата Сообщение от Danila85 Посмотреть сообщение
как с помощью C# считать информацию из текстового поля сторонней софтины?
Считать можно через Winapi. Разбираться где какое окно вам придется самому.
1
0 / 0 / 0
Регистрация: 18.08.2017
Сообщений: 16
28.06.2019, 13:31  [ТС] 3
Я смог найти окно программы по процессу и сделать его активным. И то, это я все подглядел на другом форуме. А что в приницпе дальше делать я не пойму. Могу ли я получить список контролов.. ну или их идентификаторы, или как это вообще происходит? Может быть есть какие-то статьи по работе со сторонними программами?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
 
        private void bt_start_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcessesByName("CypCut");
            if (procs.Length > 0)
            {
                if (procs[0].MainWindowHandle != IntPtr.Zero)
                    SetForegroundWindow(procs[0].MainWindowHandle);
            }
            else
            { MessageBox.Show("Программа CypCut не запущена!"); }
        }
0
196 / 139 / 103
Регистрация: 09.11.2015
Сообщений: 397
28.06.2019, 14:16 4
Цитата Сообщение от Danila85 Посмотреть сообщение
Могу ли я получить список контролов.. ну или их идентификаторы, или как это вообще происходит?
Зависит от самого приложения. Попробуйте с помощью Spy++
1
1197 / 678 / 263
Регистрация: 17.05.2015
Сообщений: 2,586
28.06.2019, 14:39 5
Лучший ответ Сообщение было отмечено Danila85 как решение

Решение

Danila85, все что идет дальше справедливо для форм, и я не уверен будет ли работать в других технологиях.
Получаем хэндл окна
C#
1
2
3
4
5
6
7
8
9
10
11
12
static IntPtr Get(string name)
        {
            IntPtr hWnd = IntPtr.Zero;
            foreach (Process pList in Process.GetProcesses())
            {
                if (pList.MainWindowTitle.Contains(name))
                {
                    hWnd = pList.MainWindowHandle;
                }
            }
            return hWnd;
        }
Затем методом GetChildWindows из этого класса получим хэндлы контролов с этого окна
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
55
56
57
58
59
60
61
62
63
public static class Helper
    {
        public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
 
        [DllImport("user32.Dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static public extern IntPtr GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount);
 
        private static bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            GCHandle gch = GCHandle.FromIntPtr(pointer);
            List<IntPtr> list = gch.Target as List<IntPtr>;
            if (list == null)
                throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
            list.Add(handle);
            return true;
        }
 
        public static List<IntPtr> GetChildWindows(IntPtr parent)
        {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle listHandle = GCHandle.Alloc(result);
            try
            {
                Win32Callback childProc = new Win32Callback(EnumWindow);
                EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
            }
            finally
            {
                if (listHandle.IsAllocated)
                    listHandle.Free();
            }
            return result;
        }
 
        public static string GetWinClass(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero)
                return null;
            StringBuilder classname = new StringBuilder(100);
            IntPtr result = GetClassName(hwnd, classname, classname.Capacity);
            if (result != IntPtr.Zero)
                return classname.ToString();
            return null;
        }
 
        public static IEnumerable<IntPtr> EnumAllWindows(IntPtr hwnd, string childClassName)
        {
            List<IntPtr> children = GetChildWindows(hwnd);
            if (children == null)
                yield break;
            foreach (IntPtr child in children)
            {
                if (GetWinClass(child) == childClassName)
                    yield return child;
                foreach (var childchild in EnumAllWindows(child, childClassName))
                    yield return childchild;
            }
        }
    }
Ну и с помощью этого класса получим текст на этих контролах
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
public class GetTextTestClass
    {
 
        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        public static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
 
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SendMessage(int hWnd, int Msg, int wparam, int lparam);
 
        const int WM_GETTEXT = 0x000D;
        const int WM_GETTEXTLENGTH = 0x000E;
 
        public string GetControlText(IntPtr hWnd)
        {
 
            // Get the size of the string required to hold the window title (including trailing null.) 
            Int32 titleSize = SendMessage((int)hWnd, WM_GETTEXTLENGTH, 0, 0).ToInt32();
 
            // If titleSize is 0, there is no title so return an empty string (or null)
            if (titleSize == 0)
                return String.Empty;
 
            StringBuilder title = new StringBuilder(titleSize + 1);
 
            SendMessage(hWnd, (int)WM_GETTEXT, title.Capacity, title);
 
            return title.ToString();
        }
    }
И да, все это я нашел на stackoverflow
1
0 / 0 / 0
Регистрация: 18.08.2017
Сообщений: 16
28.06.2019, 14:50  [ТС] 6
Спасибо большое, сейчас буду пробовать!
0
0 / 0 / 0
Регистрация: 18.08.2017
Сообщений: 16
06.08.2019, 15:02  [ТС] 7
Спустя месяц депрессий и запоев у меня все-таки все заработало! Я смог достать текст лога, ура! Теперь у меня назрел фундаментальный вопрос. Как будет правильнее организовать работу программы? Поставить постоянный цикл на считываение лога каждые X секунд? Или может быть есть какая-то функция, которая ловит событие изменения состояния контрола?
0
1197 / 678 / 263
Регистрация: 17.05.2015
Сообщений: 2,586
09.08.2019, 07:43 8
Нет такой функции, разумеется. Только таймером
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.08.2019, 07:43

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Как вывести текст на поверхность формы стороннего приложения?
Как вывести текст на поверхность формы не своего приложения? А лучше, как вывести поверх всего...

Как программно эмулировать Drag&drop файла на окно стороннего приложения
ну собственно вопрос в названии к окну никакого отношения не имею и оно не на net, просто найдено...

Как "заморозить" процесс стороннего приложения
Ну вот например как ∂OllyDbg или ∞Visual Studio при дебаге программы. Надо остановить процесс на...

Запуск стороннего приложения
Здравствуйте! Возникла проблема с запуском стороннего приложения. Имеется консольное приложение,...


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

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

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