|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Прога1 посылает сообщение в сторону Прога2. Прога2 -запущена под CURRENT_USER и должна отобразить Tray Notification (сообщение в области иконки приложения в трее). Если Прога1 запущена под тем же CURRENT_USER -то без проблем. А вот если Прога1 запущена под SYSTEM (Win NT Service), то сообщение не проходит. Причем пока не разобрался, то ли FindWindow(Ex) не находит окна, то ли SendMessage не срабатывает. Можно это как-то разрулить? Детский вариант с таймером в Прога2 и общим буфером-помойкой типа файла или БД точно не охота. Другую неосвоенную технологию типа NamedPipes как-то тоже не хочется. Хочется SendMessage(WM_COPYDATA). ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2014, 20:17 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Дмитрий77то ли FindWindow(Ex) не находит окна, то ли SendMessage не срабатывает. Можно это как-то разрулить? Прочитать про FindWindow(ex) в MSDN. авторIf the function succeeds, the return value is a handle to the window that has the specified class name and window name. If the function fails, the return value is NULL . To get extended error information, call GetLastError. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2014, 21:47 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
А еще можно пофантазировать. Допустим админ приходит к юзеру, запускает админскую прогу под своей админской учеткой, а в это время невидимая беловская юзерская прога начинает копаться в окнах админской. Кнопочки жать, например. Чисто в целях самообразования, а не в поисках выгоды или для вредительства. Впрочем, админа это не волнует, он уже рвет с опы последние жидкие волосы. С точки зрения безопасности выглядит не очень. Не исключено, что между разными учетками вообще нельзя посылать сообщения, я об этом до сих пор не задумывался. Попробуй запустить под разными учетками, кроме SYSTEM. А так же под разными типами, под админами, под админом и юзером, под юзерами. Хотя если под админами не заработает, другие варианты пробовать бессмысленно, придется осваивать неосвоенную технологию типа NamedPipes. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2014, 21:55 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Можно еще повиснуть винсоком на свободном tcp-порту, но для этого скорее всего потребуется разрешение брандмауэра. Есть еще недетский вариант с файлом, но без таймера, с функцией FindFirstChangeNotification, которая следит за изменениями файловой системы в указанной папке. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2014, 22:04 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Antonariy, просто есть готовое красивое решение: Хочу понять логику "уведомлений в трей". А как грамотно организовать "очередь сообщений" Подумал, не впихнуть ли его в мою старую прогу. Но там блин логическая часть умеет запускаться "как сервис", а трей сам по себе - отдельным exe-шником. Я погуглил, похоже если это и будет работать при каких-то условиях (разрешить взаимодействие с рабочим столом), то только на XP. Да и то не факт, "сервисы" то у меня малость липовые. Попробую глянуть на NamedPipes, если там совсем просто может воспользуюсь. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.01.2014, 22:24 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Antonariyпридется осваивать неосвоенную технологию типа NamedPipes. Пытались уже. Здесь отчет об этой попытке. Не будет это в VB6 нормально работать. AntonariyМожно еще повиснуть винсоком на свободном tcp-порту, но для этого скорее всего потребуется разрешение брандмауэра. С портами что-то не хочется после такого комментария. Вот на это попробую глянуть. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 01:47 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Дмитрий77 Вот на это попробую глянуть. Что-то там не так с этой Shared Memory. По крайней мере VSVLAD в своем простом классе явно что-то упустил, а что - надо во все это влезать. То информация читается из памяти, то не читается и надо комп перегружать. И самое главное, принцип ничем не отличается от пуляния файлами. Приемник все равно должен читать память по таймеру (ну либо бесконечным циклом в отдельном потоке что в VB6 будем считать нереализуемо). Информацию желательно читать по принципу CallBack -что реализовано в SendMessage -> WndProc. (как только так сразу) Ну либо в контролах типа InternetTransfer или WinSock. А от того что ее писать в файл, в БД, в реестр или в память и потом читать по таймеру - детский принцип не меняется. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 03:35 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
AntonariyНе исключено, что между разными учетками вообще нельзя посылать сообщения, Поигрался. На XP можно. В свойствах сервиса надо установить галку Разрешить взаимодействие с рабочим столом . А вот на всех начиная с Висты дальше-хуже. Windows 8 Interactive Services Detection Через 10 задниц это "взаимодействие" запускается (я час возился на Win2012 R2), но при этом SendMessage стреляет мимо реального рабочего стола, т.е. не попадает в целевое окно, а стреляет в Session 0, в которой target-окно по определению отсутствует (на Виста и выше). Так что даже не знаю как разруливать кроме как через таймер + Shared Детский Сад (тип детского сада можно выбрать по желанию). Скорее всего потыкаюсь еще чуть и откажусь пока здесь от красивой идеи с Notifications. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 05:51 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Дмитрий77Antonariyпридется осваивать неосвоенную технологию типа NamedPipes. Пытались уже. Здесь отчет об этой попытке. Не будет это в VB6 нормально работать.Да все работает на системах от 2к и выше. Просто ты умудрился найти наиболее бредовый пример. Попробуй это . ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 11:36 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Дмитрий77Но там блин логическая часть умеет запускаться "как сервис", а трей сам по себе - отдельным exe-шником. Я погуглил, похоже если это и будет работать при каких-то условиях (разрешить взаимодействие с рабочим столом), то только на XP. Да и то не факт, "сервисы" то у меня малость липовые.Существует nt service control, который позволяет сервису создавать окна и пихать иконки в трей из одного и того же exe. А как же твои "липовые" сервисы устроены? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 11:39 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
AntonariyА как же твои "липовые" сервисы устроены? NSSM Service Manager На фига изобретать паравоз если можно взять его в аренду. Клиенты дружно кричали "хотим паравоз", они его получили. А о том что этот "сервис" элементарно киллит врученный стандартный exe-шник при остановке (не всегда удачно), кажется поджирает процессор и в случае ошибки msgbox "висит" где-то под Local System невидимый - детали, про кот. автор т.е. я деликатно умалчивает. А что делать? Через API я настраиваю только некоторые атрибуты типа автозапуска. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 18:55 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
AntonariyПросто ты умудрился найти наиболее бредовый пример. Попробуй это . Я поигрался. Ну вот смотри. Допустим пайп-сервис шлет сообщение в Command1: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
За счет PIPE_WAIT сервер будет висеть, пока клиент это сообщение не прочитает. Если б клиент читал его сразу, то это еще нормально (принцип работы SendMessage которая тоже должна вернуть результат). Но я не знаю другого способа кроме таймера на клиенте чтоб прочитать результат, а это время (3 сек, 1 сек, 0,5 сек) - непозволительная роскошь для единственного потока на сервере. Попробую сформулировать. В случае с SendMessage : Сервер -проверяет наличие клиента (окно hwndTarget) и только при его наличии шлет SendMessage -получает результат (возврат от SendMessage от клиента) считай сразу, т.к. WndProc клиента отрабатывает мгновенно и она быстрая - т.е. сервер не висит в ожидании Клиент - если сервер не запущен, то он сообщение и не получит - сразу словит сообщение через WndProc, отработает его там и отпустит сервер вернув результат через WndProc В случае с Pipe : Сервер -не может проверить наличие клиента, поэтому вынужден писать команду в pipe ПО-ЛЮБОМУ -если клиента нет(не запущен), то это висяк навечно. Если клиент есть, то это висяк на время интервала таймера клиента - т.е. недопустимая задержка(висим) Клиент: -вынужден долбить пайп по таймеру, т.е. задержка в получении сообщения -если сервер не запущен (пайп не открыт, в пайпе пусто), то будет висеть. Хотя последнее вроде лечится Код: vbnet 1. 2. 3. 4.
И вот скажи, как мне все это разруливать? Поясню еще: 1) Сервер может быть запущен, а клиент нет. Сервер работает как сервис без менеджера, кот. выводит иконку в трей (в фоновом режиме). 2) Клиент может быть запущен, а сервер - нет. Т.е. есть иконка, а само приложение не запущено. Прелесть SendMessage в принципе: послал-принял-забыл Без висяков на стороне сервера и без таймер-долбежки на стороне клиента. Таймер-долбежка это еще ладно. Но в этом случае сервер должен скидывать информацию в буфер (пусть в пайп) и забывать про нее. С БД я знаю как это сделать: Сервер пишет команды в таблицу БД (нумерует по возрастанию). Клиент эти команды по таймеру все читает (прочитал, удалил запись из БД). Ну при этом надо не забыть тупо очистить таблицу БД при запуске клиента (если клиент не был запущен и там накопились неактуальные команды). И я этот принцип в одном месте использую (быстрое обновление отдельных строк в ListView, кот. "отображает" большую таблицу из БД). А вот как тоже самое, т.е. без висяка сервера (хотя б с таймером) реализовать на пайпах, я не знаю. Т.е. 1) Сервер пишет команды в пайп по мере их накопления с соблюдением последовательности, при этом не висит и не ждет 2) Клиент читает команды по таймеру (с соблюдением последовательности) и очищает содержимое пайпа 3) Клиент очищает пайп при запуске. Как считаешь, ты же эту технологию вроде изучил, оно возможно? Если да, то м.б. имеет смысл углубляться в документацию и изучать. Если нет, то это будет потраченное время. Просто я уже второй день, извини психую. А вариантов не так много: 1) Полностью отказаться от идеи Tray Notifications для данного приложения до лучших времен (когда меня хватит на то чтоб полностью переписать прогу на .Net). 2) Вставить код что есть (WM_COPYDATA), с глупым комментом: А вот в режиме As Service это работать извините не будет, ну если на XP только. Некрасиво как-то и с намеком на нек. безграмотность автора. 3) Скрипя зубами написать таки взаимодействие но это не два дня, даже если через БД. И через БД честно не очень хочется: лишняя таблица + лишний клиент на БД - сильное усложнение клиента (который трей icon) да и всей проги - совместимость структуры БД с предыдущими версиями и т.д. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.01.2014, 19:56 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Дмитрий77 В случае с Pipe: Сервер -не может проверить наличие клиентаЧего это вдруг? Отправка сообщений не единственный способ проверить наличие клиента. Самый очевидный — поискать процесс. Дмитрий77 Как считаешь, ты же эту технологию вроде изучил, оно возможно? Увы Мой практический опыт межпроцессного взаимодействия ограничен ActiveX exe, остального по верхам нахватался. Дмитрий77 Если да, то м.б. имеет смысл углубляться в документацию и изучать.Обычно с этого начинают. Вот нужная тебе статейка , должна помочь. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.01.2014, 00:03 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Antonariy, не буду я влезать в эти дебри. Есть проверенный способ общения через таблицу БД, им и воспользуюсь, раз уж SendMessage не прокатывает, тем более от таймера на клиенте все равно не отвертишься (задержка появления уведомления порядка секунды думаю здесь как раз не проблема). А с асинхронностями я игрался давно в другом месте (скачивание файла из интернета) и ни к чему это не привело. С этими Notification и их очередью и так куча логической и рутинной работы. Запутывать код еще "новыми технологиями", да ну его. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.01.2014, 01:48 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Ну через БД+таймер то я обмен сделал, немного остыл. Но все таки эти пайпы покоя не дают. AntonariyВот нужная тебе статейка , должна помочь. Статейку то я почитал. И вот этот код: Named Pipe Server Using Overlapped I/O даже начал на VB6 потихоньку перекатывать. Но я все-таки не понимаю ответа на свой основной вопрос. Пайп это вообще что? Буфер там есть? Ну т.е. создал я пайп при старте сервера: hPipe = CreateNamedPipe У меня получается, что 1) Если сервер пишет в пайп ConnectNamedPipe WriteFile FlushFileBuffers DisconnectNamedPipe то сервер висит пока клиент не прочтет посланную информацию 2) Если клиент читает из пайпа CallNamedPipe (даже с NMPWAIT_NOWAIT) то клиент висит пока сервер не пошлет ему чего-нибудь Иными словами, висяки на сервере и клиенте, роскоши типа WaitForMultipleObjects или бесконечных Do Loop я в единственном потоке позволить себе не могу. А я хочу: 1) Сервер положил Message в пайп, забыл про него и занимается дальше своими делами (без гарантии доставки клиенту) 2) Клиент по таймеру пришел в пайп, и если есть Message, то прочел его. А если нет, то не ждет и занимается дальше своими делами. 3) Дополнительно хочу чтоб пайп очищался при старте клиента И сдается мне что так не получится. Или нужен механизм на клиенте, чтоб не по таймеру, а пайп стучал клиенту про новый message как только Message в пайпе появился. Есть какие соображения ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2014, 17:16 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
Дмитрий77 Статейку то я почитал.Мало читаешь. Плохо и невнимательно. Дмитрий77 Пайп это вообще что? Буфер там есть? http://ru.wikipedia.org/wiki/???????????_????? http://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx Нет там никакого буфера. Считай, что это файл. Дмитрий77 1) Если сервер пишет в пайп ConnectNamedPipe WriteFile FlushFileBuffers DisconnectNamedPipe то сервер висит пока клиент не прочтет посланную информацию Ну так не пиши, пока клиент не запущен. Я не понимаю, что за детсадовкие проблемы с определением наличия в памяти нужного процесса? Дмитрий772) Если клиент читает из пайпа CallNamedPipe (даже с NMPWAIT_NOWAIT) то клиент висит пока сервер не пошлет ему чего-нибудь Справка по CallNamedPipe:Calling CallNamedPipe is equivalent to calling the CreateFile ( or WaitNamedPipe, if CreateFile cannot open the pipe immediately ), TransactNamedPipe, and CloseHandle functions.Используй CreateFile/CloseHandle, чтобы проверить доступность канала, тогда клиент не будет висел в негласно вызванной WaitNamedPipe. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2014, 18:06 |
|
SendMessage(WM_COPYDATA) Передатчик (SYSTEM) -> Приемник (CURRENT USER)
|
|||
---|---|---|---|
#18+
AntonariyМало читаешь. Плохо и невнимательно?Там очень много понаписано. AntonariyНу так не пиши, пока клиент не запущен. Я не понимаю, что за детсадовкие проблемы с определением наличия в памяти нужного процесса?...Используй CreateFile/CloseHandle Да не детсадовские это проблемы, так мне все админы и рассказали что у них запущено. Сам же писал про безопасность. И не слишком ли все это сложно -куча таких телодвижений. Короче я сходил к коллегам из C++ за советом. плохо они о пайпах отзываются. Но указатель на правильное решение таки был дан: Изопропил mailslot для связи без гарантии доставки и без установления соединения http://msdn.microsoft.com/en-us/library/windows/desktop/aa365794(v=vs.85).aspx http://www.codeproject.com/Articles/8527/Using-Mailslots-for-Interprocess-Communication... MasterZivЭто более похоже на mailSlots (от MS, параллельная спецификация к NamedPipes). === Документация простенькая и понятная. В точности отвечает поставленной задаче. Уже все сделал, душа радуется. Терминология чуть другая: КЛИЕНТ - тот кто ПОСЫЛАЕТ СЕРВЕР - тот кто ПРИНИМАЕТ Проверил на XP и на Win 2012 R2 и из под "As Service" тоже. Отлично все работает(сервер с TrayIcon -таймер на 1 сек). Я ниже свой тест-пример вложил. При запуске первого экземпляра активируется "сервер", 2-й и так далее экземпляры будут "только клиентами" (могут слать сообщения серверу). СЕРВЕР-ПРИЕМНИК: Код: vbnet 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. 78. 79. 80. 81. 82.
КЛИЕНТ - ПЕРЕДАТЧИК: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2014, 01:09 |
|
|
start [/forum/topic.php?fid=60&msg=38522526&tid=2156573]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
38ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 142ms |
0 / 0 |