Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.72
Jazz411
85 / 33 / 12
Регистрация: 12.03.2011
Сообщений: 234
Записей в блоге: 2
#1

доступ к данным другой программы - C#

03.09.2011, 04:52. Просмотров 4352. Ответов 17
Метки нет (Все метки)

Доброго времени суток

Есть некая программа с которой грубо говоря нужно взять данные, объясните как собственно говоря это происходит или дайте ссылку на учебники.
http://www.cyberforum.ru/csharp-net/thread712971.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.09.2011, 04:52
Я подобрал для вас темы с готовыми решениями и ответами на вопрос доступ к данным другой программы (C#):

Доступ к функционалу другой программы
Всем привет! На работе столкнулся с проблемой - очень часто крашится рабочая...

Асинхронный доступ к статическим данным
Всем привет. Ситуация такая: Есть асинхронные методы которые используют общие...

Многопоточный сервер: доступ клиентов к данным
Здравствуйте нашёл в интернете многопоточный сервер using System; using...

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

Доступ из одного проекта к данным, сериализованым в другом
У меня есть проект Формс для работы с масивом двухмерных масивов. То есть...

17
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
03.09.2011, 05:18 #2
Jazz411, всё зависит от того какие данные Вам нужны и что за приложение.
  • Для получения списка элементов на форме стороннего приложения можно использовать EnumChildWindows;
  • Для получения/изменения текста в текстовых полях, кнопках - можно использовать SendMessage с WM_GETTEXT;
  • Для некоторых компонентов есть специальные сообщения отличные от WM_*;
  • Для чтения/записи памяти стороннего процесса можно использовать [Read]WriteProcessMemory;
  • и т.д. и т.п. (список можно продолжить);
3
Jazz411
85 / 33 / 12
Регистрация: 12.03.2011
Сообщений: 234
Записей в блоге: 2
03.09.2011, 05:44  [ТС] #3
чтения данных таблицы, это к чему относится?
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
03.09.2011, 05:57 #4
Jazz411, смотря что за таблицы. Если ListView, то вот описание. Если DataGridView, то тут всё сложнее - для него нет API (или оно недокументировано).

Для исследования программ используйте либо Spy++ (идёт вместе с VS) либо WinSpy.
Для изучения сообщений посылаемых стандартным контролам есть приложение ControlSpy от MS.
0
Fredi
Заблокирован
03.09.2011, 21:21 #5
Цитата Сообщение от SSTREGG Посмотреть сообщение
Для получения/изменения текста в текстовых полях, кнопках - можно использовать SendMessage с WM_GETTEXT;
SSTREGG, как изменить по пойманным дескрипторам названия или текст контролов?
Вот пример
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
64
65
66
    using System.Runtime.InteropServices;
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
        }
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
 
        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
 
        
        public static List<IntPtr> GetChildWindows(IntPtr parent)
        {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle listHandle = GCHandle.Alloc(result);
            try
            {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
            }
            finally
            {
                if (listHandle.IsAllocated)
                    listHandle.Free();
            }
            return result;
        }
 
       
        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);
            //  You can modify this to check to see if you want to cancel the operation, then return a null here
            return true;
        }
 
       
        public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
 
      
 
        private void button1_Click(object sender, EventArgs e)
        {
            List<IntPtr> ls = new List<IntPtr>();
            string enum_ = string.Empty;
             IntPtr hWnd = FindWindow(null, "Калькулятор Плюс");
             if (!hWnd.Equals(IntPtr.Zero))
               ls = GetChildWindows(hWnd);
             Array.ForEach(ls.ToArray(), i => enum_ += i.ToString() + Environment.NewLine);
 
             MessageBox.Show(enum_);
        }
 
    }
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
04.09.2011, 00:10 #6
У контролов нет имён, у них есть классы (неизменяемые) и текст содержащийся в них (это относится не ко всем контролам).
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
        [DllImport( "user32.dll", SetLastError = true )]
        private static extern IntPtr FindWindow ( string lpClassName, string lpWindowName );
 
        [DllImport( "user32", SetLastError = true )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool EnumChildWindows ( IntPtr window, EnumWindowProc callback, IntPtr i );
 
        [DllImport( "user32.dll", SetLastError = true )]
        static extern IntPtr SendMessage ( IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam );
 
        public static List<IntPtr> GetChildWindows ( IntPtr parent ) {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle listHandle = GCHandle.Alloc( result );
            try {
                EnumChildWindows( parent, EnumWindow, GCHandle.ToIntPtr( listHandle ) );
            } finally {
                if ( listHandle.IsAllocated )
                    listHandle.Free();
            }
            return result;
        }
 
 
        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 );
            //  You can modify this to check to see if you want to cancel the operation, then return a null here
            return true;
        }
 
 
        public delegate bool EnumWindowProc ( IntPtr hWnd, IntPtr parameter );
 
        private void button1_Click ( object sender, EventArgs e ) {
            List<IntPtr> ls = new List<IntPtr>();
            string enum_ = string.Empty;
            IntPtr hWnd = FindWindow( null, "Калькулятор" );
            if ( !hWnd.Equals( IntPtr.Zero ) )
                ls = GetChildWindows( hWnd );
            Array.ForEach( ls.ToArray(), i => SendMessage(i, 0x000CU /* WM_SETTEXT */, IntPtr.Zero, "S") );
        }
1
Fredi
Заблокирован
04.09.2011, 00:42 #7
Понятно. Значит можно только сделать ввод в текстовые поля. Тоже неплохо.
Спасибо.
А как поймать конкретное текстовое поле и в него ввести нужное значение? Может необходимо ловить по имени, вернее по классу? Вот пример
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
using System;
using System.Text;
using System.Runtime.InteropServices;
 
namespace ConsoleApplication1
{
    class Program
    {
        public delegate bool WindowEnumDelegate(IntPtr hwnd,
                                                int lParam);
 
        // declare the API function to enumerate child windows
        [DllImport("user32.dll")]
        public static extern int EnumChildWindows(IntPtr hwnd,
                                                  WindowEnumDelegate del,
                                                  int lParam);
 
        // declare the GetWindowText API function
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hwnd,
                                               StringBuilder bld, int size);
 
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
 
        static void Main(string[] args)
        {
            // instantiate the delegate
            WindowEnumDelegate del
                   = new WindowEnumDelegate(WindowEnumProc);
            IntPtr hWnd = FindWindow(null, "Калькулятор Плюс");
            if (!hWnd.Equals(IntPtr.Zero))           
                EnumChildWindows(hWnd, del, 0);
 
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
 
        public static bool WindowEnumProc(IntPtr hwnd, int lParam)
        {
            // get the text from the window
            StringBuilder bld = new StringBuilder(256);
            GetWindowText(hwnd, bld, 256);
            string text = bld.ToString();
 
            if (text.Length > 0)
            {
                Console.WriteLine(text);
            }
            return true;
        }
    }
}
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
04.09.2011, 00:57 #8
Цитата Сообщение от Fredi Посмотреть сообщение
Может необходимо ловить по имени, вернее по классу
Не получится, т.к. на форме может быть множество контролов с одним классом. Можно только выделить компоненты в отдельные группы, поделенные по классам, и уже искать нужный компонент в группе методом тыка.
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
        [DllImport( "user32.dll", SetLastError = true )]
        private static extern IntPtr FindWindow ( string lpClassName, string lpWindowName );
 
        [DllImport( "user32", SetLastError = true )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool EnumChildWindows ( IntPtr window, EnumWindowProc callback, IntPtr i );
 
        [DllImport( "user32.dll", SetLastError = true )]
        static extern IntPtr SendMessage ( IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam );
 
        [DllImport( "user32.dll", SetLastError = true )]
        static extern int GetClassName ( IntPtr hWnd, StringBuilder lpClassName, int nCount );
 
        public static List<IntPtr> GetChildWindows ( IntPtr parent ) {
            return GetChildWindows( parent, null );
        }
 
        public static List<IntPtr> GetChildWindows ( IntPtr parent, string className ) {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle listHandle = GCHandle.Alloc( result );
            try {
                EnumChildWindows(
                    parent,
                    ( handle, pointer ) => {
                        if ( className != null ) {
                            if ( !string.Equals( GetWndClassName( handle ), className,
                                    StringComparison.CurrentCultureIgnoreCase ) )
                                return true;
                        }
 
                        var gch = GCHandle.FromIntPtr( pointer );
                        var 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;
                    }, GCHandle.ToIntPtr( listHandle ) );
            } finally {
                if ( listHandle.IsAllocated )
                    listHandle.Free();
            }
            return result;
        }
 
        public static string GetWndClassName ( IntPtr hWnd ) {
            var sb = new StringBuilder( 256 );
            int retVal = 0;
 
            retVal = GetClassName( hWnd, sb, sb.Capacity );
 
            return sb.ToString( 0, retVal );
        }
 
        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 );
            //  You can modify this to check to see if you want to cancel the operation, then return a null here
            return true;
        }
 
 
        public delegate bool EnumWindowProc ( IntPtr hWnd, IntPtr parameter );
 
        private void button1_Click ( object sender, EventArgs e ) {
            List<IntPtr> ls = new List<IntPtr>();
            string enum_ = string.Empty;
            IntPtr hWnd = FindWindow( null, "Калькулятор" );
            if ( !hWnd.Equals( IntPtr.Zero ) )
                ls = GetChildWindows( hWnd, "Button" );
            Array.ForEach( ls.ToArray(), i => SendMessage( i, 0x000CU, IntPtr.Zero, "S" ) );
        }
1
Fredi
Заблокирован
04.09.2011, 01:27 #9
Цитата Сообщение от SSTREGG Посмотреть сообщение
Не получится
Думаю, что можно это обойти. При итерации по контролам, они всегда перечисляются по заданному порядку. Методом тыка узнать, какой котрол идет под каким индексом и в определенный контрол вводить определенное значение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
      private void button1_Click(object sender, EventArgs e)
        {
            List<IntPtr> ls = new List<IntPtr>();
            string enum_ = string.Empty;
            IntPtr hWnd = FindWindow(null, "Калькулятор Плюс");
            if (!hWnd.Equals(IntPtr.Zero))
                ls = GetChildWindows(hWnd);
            for (int i = 0; i < ls.Count; i++)
            {
                if (i == 0) SendMessage(ls[i], 0x000CU, IntPtr.Zero, "Сергей");
                else if (i == 3) SendMessage(ls[i], 0x000CU, IntPtr.Zero, "Виктор");
            }
          
        }
Походу тоже самое можно сделать и в браузере
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
04.09.2011, 01:33 #10
Цитата Сообщение от Fredi Посмотреть сообщение
При итерации по контролам, они всегда перечисляются по заданному порядку. Методом тыка узнать, какой котрол идет под каким индексом и в определенный контрол вводить определенное значение
Я это и имел ввиду
Цитата Сообщение от Fredi Посмотреть сообщение
Думаю, что тоже самое можно сделать и в браузере
Если внутри отображаемой страницы, то нет. Все браузеры производят рендеринг компонентов самостоятельно, а не создают их как это принято в винде. Поэтому при отображении мы получаем монолитное изображение в виде компонента, и все изменения отображаются браузером самостоятельно.
1
Fredi
Заблокирован
04.09.2011, 01:36 #11
Цитата Сообщение от SSTREGG Посмотреть сообщение
Если внутри отображаемой страницы, то нет.
Понятно. Еще раз спасибо.
0
Jazz411
85 / 33 / 12
Регистрация: 12.03.2011
Сообщений: 234
Записей в блоге: 2
04.09.2011, 01:47  [ТС] #12
так а я продолжу тему в течении дня с помощью SPY++ я наконец нашел тот элемент который мне был нужен вот он TDBGrid, предполагаю что сама программа написана на с++ builder, и теперь вопрос как к нему добраться?
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
04.09.2011, 01:58 #13
Jazz411, это самописный компонент, который не является стандартным в Windows. Официальных API я к нему не нашел. Нужно анализировать с помощью Spy++ что куда и как передается. В Spy++ для этого есть окно Spy -> Log Messages.

p.s. Мне с этим компонентом работать не приходилось.
0
Jazz411
85 / 33 / 12
Регистрация: 12.03.2011
Сообщений: 234
Записей в блоге: 2
04.09.2011, 02:01  [ТС] #14
мм интересно конечно я посмотреть то смогу, но вот на что смотреть та хоть?
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
04.09.2011, 02:20 #15
На
изображении
доступ к данным другой программы
пример работы Spy++.

Описание:
1-я колонка: номер сообщения в списке (текущем) - необязательный параметр.
2-я колонка: хендл окна которому послано сообщение
3-я колонка: тип сообщения. S - Sent (SendMessage), P - Posted (PostMessage), R - Return (возвращенное значение)
4-я колонка: имя сообщения или его номер (WM_MOUSEACTIVE или message: 0xC315 [нестандартное сообщение] к примеру)
5-я колонка и т.д. соответствуют параметрам функций SendMessage и PostMessage.
0
Jazz411
85 / 33 / 12
Регистрация: 12.03.2011
Сообщений: 234
Записей в блоге: 2
04.09.2011, 16:41  [ТС] #16
так вообще я отследил то что нужно вот результат что дальше? доступ к данным другой программы
И какой из 3, собственно, мне нужен?
0
NickoTin
Почетный модератор
Эксперт .NET
8435 / 3557 / 401
Регистрация: 14.06.2010
Сообщений: 4,512
Записей в блоге: 9
04.09.2011, 17:12 #17
Jazz411, а Вы уверены что это то что Вам нужно? С помощью этих сообщений нельзя получить данные.
WM_MOUSEACTIVE происходит когда был щелчок мышью по неактивному окну (компоненту) и оно приняло фокус.
WM_LBUTTONDOWN происходит когда был клик по окну (компоненту) левой кнопкой мыши.

Эти сообщения можно эмулировать, для создания нужного действия, но никакого результата они не вернут.
0
Jazz411
85 / 33 / 12
Регистрация: 12.03.2011
Сообщений: 234
Записей в блоге: 2
04.09.2011, 23:13  [ТС] #18
блин а че тянуть то надо? если мне нужно достать данные с ячейки?
0
04.09.2011, 23:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.09.2011, 23:13
Привет! Вот еще темы с решениями:

Получить доступ к данным выделенной строки таблицы listView
Создаю таблицу в listView следующим образом: DataTable table = new...

Доступ к данным из SQL при клике по строке в DataGridView
Проект Windows Forms @ C# Имеется табличка (далее SQLTable) в базе данных...

Как получить доступ к данным в Grid?
На форме есть Grid, я его заполняю так: mdb = New OleDbConnection...

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


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

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

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