Re[6]: Как получить сообщение из неуправляемой dll
От: Аноним  
Дата: 22.06.09 13:13
Оценка:
Здравствуйте, OLLEGator, Вы писали:

OLL>ЗЫ. Все нужные функции, вроде бы, нашёл и подключил. А не ловится и запрос в том комплексе отваливается. ((((


Ваша проблема в том, что Thread.CurrentThread.ManagedThreadId возвращает нечто левое, а вовсе не системный ThreadID. Вот так работает

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    [StructLayout(LayoutKind.Sequential)]
    unsafe public struct AsyncQuery
    {
        public /*??*/IntPtr/*??*/ handle;
        [ MarshalAs (UnmanagedType.Bool)]
        public bool is_thread;
        public UInt32 msg;
        public UInt32 answer_size;
        public void* answer_buf;
    }

    unsafe public struct TPoint
    {
        public Int32 X;
        public Int32 Y;
    }

    unsafe public struct TMsg
    {
        public IntPtr hwnd;
        public UInt32 message;
        public UInt32 wParam;
        public UInt32 lParam;
        public UInt32 time;
        public TPoint pt;
    }

    class Program
    {
        public const UInt32 MM_MESSAGE = 0x8001;

        [DllImport("D:\\Program Files\\Borland\\Delphi7\\Projects\\0Proba\\AsyncNetTest\\BIN\\AsyncTest.dll", EntryPoint = "QueryAsync")] 
        public static extern Int32 RTDBQueryAsync(ref AsyncQuery query);

        [DllImport("user32.dll", EntryPoint = "PeekMessageA")]
        public static extern bool PeekMessage(
            ref TMsg lpMsg,      // message information
            IntPtr hWnd,           // handle to window
            UInt32 wMsgFilterMin,  // first message
            UInt32 wMsgFilterMax,  // last message
            UInt32 wRemoveMsg      // removal options
        );

        [DllImport("user32.dll", EntryPoint = "GetMessageA")]
        public static extern bool GetMessage(
            ref TMsg lpMsg,      // message information
            IntPtr hWnd,           // handle to window
            UInt32 wMsgFilterMin,  // first message
            UInt32 wMsgFilterMax  // last message
        );

        [DllImport("Kernel32.dll", EntryPoint = "GetCurrentThreadId")]
        public static extern UInt32 GetCurrentThreadId();
        unsafe static void Main(string[] args)
        {
            byte * pBuf = stackalloc byte[100];
            AsyncQuery AQ = new AsyncQuery();
            // AQ.handle = (IntPtr)Thread.CurrentThread.ManagedThreadId;
            AQ.handle = (IntPtr)GetCurrentThreadId();
            AQ.is_thread = true;
            AQ.msg = MM_MESSAGE;
            AQ.answer_size = 100;
            AQ.answer_buf = pBuf;

            Int32 Ret = RTDBQueryAsync(ref AQ);
            if (Ret != -1)
            {
                TMsg Msg = new TMsg();
                while (GetMessage(ref Msg, IntPtr.Zero, 0, 0 ))
                {
                    if(Msg.message == MM_MESSAGE)
                    {
                        Console.WriteLine("Operation is completed");
                        Console.ReadLine();
                        break;
                    }
                }
            }
        }
    }
}


PS Можете меня поздравить — это моя первая "программа" на C#
Re[7]: Как получить сообщение из неуправляемой dll
От: Аноним  
Дата: 22.06.09 13:30
Оценка: +1 -1
Здравствуйте, Serginio1, Вы писали:

S>Получи номер сообщения через RegisterWindowMessage и передай его своей длл,


RegisterWindowMessage используется для того, чтобы другие процессы смогли получить идентификатор сообщения по его имени. То есть если два процесса вызовут RegisterWindowMessage с одним именем сообщения, то они получат один и тот-же идентификатор и смогут его использовать для связи друг с другом. В данном-же случае в её вызове нет ни необходимости, ни смысла.
Re[8]: Как получить сообщение из неуправляемой dll
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 22.06.09 13:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Serginio1, Вы писали:


S>>Получи номер сообщения через RegisterWindowMessage и передай его своей длл,


А>RegisterWindowMessage используется для того, чтобы другие процессы смогли получить идентификатор сообщения по его имени. То есть если два процесса вызовут RegisterWindowMessage с одним именем сообщения, то они получат один и тот-же идентификатор и смогут его использовать для связи друг с другом. В данном-же случае в её вызове нет ни необходимости, ни смысла.

Ух давненько я с винапи не работал. Спасибо. Уже потом сам понял когда написал.
и солнце б утром не вставало, когда бы не было меня
Re[8]: Как получить сообщение из неуправляемой dll
От: Pavel Dvorkin Россия  
Дата: 23.06.09 02:40
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Serginio1, Вы писали:


S>>Получи номер сообщения через RegisterWindowMessage и передай его своей длл,


А>RegisterWindowMessage используется для того, чтобы другие процессы смогли получить идентификатор сообщения по его имени. То есть если два процесса вызовут RegisterWindowMessage с одним именем сообщения, то они получат один и тот-же идентификатор и смогут его использовать для связи друг с другом. В данном-же случае в её вызове нет ни необходимости, ни смысла.


Это будет все же надежнее. Представь себе, что некое иное приложение пошлет сообщение с WM_APP+x бродкастом всем окнам. Да, это дурной стиль, но все же лучше от него защититься.
With best regards
Pavel Dvorkin
Re[7]: Как получить сообщение из неуправляемой dll
От: Pavel Dvorkin Россия  
Дата: 23.06.09 02:43
Оценка:
Здравствуйте, Аноним, Вы писали:


А>PS Можете меня поздравить — это моя первая "программа" на C#


Поздравляю. Но это не твоя первая программа на C#, а просто консольное Win API приложение, переведенное на C#
With best regards
Pavel Dvorkin
Re[9]: Как получить сообщение из неуправляемой dll
От: Аноним  
Дата: 23.06.09 04:01
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Это будет все же надежнее. Представь себе, что некое иное приложение пошлет сообщение с WM_APP+x бродкастом всем окнам. Да, это дурной стиль, но все же лучше от него защититься.


А Вы представьте себе, что потолок обвалится Ну может же такое быть, но это не значит, что надо срочно расставлять подпорки по квартире, тем более, что всё равно не помогут. От дурного стиля защититься невозможно.
В часности, это стороннее приложение с тем-же успехом может отправить broadcast с идентификатором из диапазона, возвращаемого RegisterWindowMessage. С дуру. Это стороннее приложение просто может вызвать RegisterWindowMessage с тем-же именем. Но к данному случаю это не относится, если сообщение отправляется потоку — бродкастов потокам не бывает. Тем не менее, и это не гарантия — дурное сторонне приложение вполне способно с дуру отправить своё сообщение нашему потоку. В общем, RegisterWindowMessage никоим образом не гарантирует от опасности нарваться на дурака, а значит и смысла в его использовании нет. Кто захочет, тот нагадит.

PD>Поздравляю. Но это не твоя первая программа на C#, а просто консольное Win API приложение, переведенное на C#


Разве от этого оно превратилось в приложение на бейсике или яве
Re[9]: Как получить сообщение из неуправляемой dll
От: Аноним  
Дата: 23.06.09 04:41
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

И кстати, совсем ведь забыл, даже проверять пришлось Сообщения с номером WM_USER и выше система просто не рассылает бродкастом, так что выбор в качестве сообщения WM_APP + x уже гарантирует от этого
Re[10]: Как получить сообщение из неуправляемой dll
От: Pavel Dvorkin Россия  
Дата: 23.06.09 11:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Pavel Dvorkin, Вы писали:


А>И кстати, совсем ведь забыл, даже проверять пришлось Сообщения с номером WM_USER и выше система просто не рассылает бродкастом,


При чем тут система ? Я из своего приложения его разошлю

так что выбор в качестве сообщения WM_APP + x уже гарантирует от этого

От чего гарантирует ? От того, что некое глупое приложение его не пошлет ?
With best regards
Pavel Dvorkin
Re[10]: Как получить сообщение из неуправляемой dll
От: Pavel Dvorkin Россия  
Дата: 23.06.09 11:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А Вы представьте себе, что потолок обвалится Ну может же такое быть, но это не значит, что надо срочно расставлять подпорки по квартире, тем более, что всё равно не помогут. От дурного стиля защититься невозможно.




А>В часности, это стороннее приложение с тем-же успехом может отправить broadcast с идентификатором из диапазона, возвращаемого RegisterWindowMessage. С дуру.


Ты его номер сначала получи

>Это стороннее приложение просто может вызвать RegisterWindowMessage с тем-же именем.


Дизассемблить мое приложение будешь в поисках этой строки или же API Mon запустишь для этой цели ?

>Но к данному случаю это не относится, если сообщение отправляется потоку — бродкастов потокам не бывает.


Верно, но обсуждался еще и вариант посылки окну.

>Тем не менее, и это не гарантия — дурное сторонне приложение вполне способно с дуру отправить своё сообщение нашему потоку. В общем, RegisterWindowMessage никоим образом не гарантирует от опасности нарваться на дурака, а значит и смысла в его использовании нет.


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


PD>>Поздравляю. Но это не твоя первая программа на C#, а просто консольное Win API приложение, переведенное на C#


А>Разве от этого оно превратилось в приложение на бейсике или яве


Нет
With best regards
Pavel Dvorkin
Re[11]: Как получить сообщение из неуправляемой dll
От: Аноним  
Дата: 23.06.09 12:11
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Pavel Dvorkin, Вы писали:


А>>И кстати, совсем ведь забыл, даже проверять пришлось Сообщения с номером WM_USER и выше система просто не рассылает бродкастом,


PD>При чем тут система ? Я из своего приложения его разошлю


PD>так что выбор в качестве сообщения WM_APP + x уже гарантирует от этого


PD>От чего гарантирует ? От того, что некое глупое приложение его не пошлет ?


Сами Вы не можете ничего разослать. Вы можете только попросить систему сделать это.

Вы не поняли. Я это тоже не сразу вспомнил, даже проверять пришлось. Попытка выполнить SendMessage(HWND_BROADCAST, MsgId, ...) с MsgId из диапазона от WM_USER до 0xC000 — 1 ни к чему не приводит, сообщение просто не рассылается. И это и есть гарантия.

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

В общем, дело явно перешло в разряд "спор ради спора", а мне такие дискуссии не интересны. Хотите регистрировать, регистрируйте на здоровье
Re[12]: Большое спасибо! из неуправляемой dll
От: OLLEGator  
Дата: 23.06.09 13:38
Оценка:
Здравствуйте, Уважаемые участники, Вы писали: Много ценных советов.

Большое спасибо всем, кто пытался помочь. Наконец-то получилось поймать сообщения!!....
Прошу прощения, но рабочий вариант опубликую чуть позже.
Ещё раз БОЛЬШОЕ СПАСИБО!.

З.Ы. Сообщения получилось ловить в потоке, без окон.
Вскрытие покажет....
(кто знает на латыни, киньте в личку)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.