Сообщений 23 Оценка 41 [+0/-1] Оценить |
Введение Как это сделать Послесловие |
Исходные тексты примера к статье
Часто возникает желание встроить в свою программу что-нибудь, к чему пользователи привыкли или, по крайней мере, не боятся. Так, может захотеться встроить рассылку уведомлений/сообщений по сети, использующую механизм "net send".
Если стандартная реализация net send вас устраивает, то можно смело вызвать ShellExecute для net.exe и не читать статью до конца. Минимум кода и предельная простота:
ShellExecute( hWnd, "open", "net.exe", " send " + sComputerName + "\"Hello!\"", "%SystemRoot%\\system32", SW_HIDE ); |
Однако такие сообщения будут приходить от имени компьютера, пославшего их. Естественно, если встраивать рассылку сообщений в некую сервисную программу, то желательно, чтобы и сообщения приходили от имени этой программы, но такой подход этого не позволит.
Чтобы понять, с помощью чего отправляются сообщения, пришлось взглянуть на net.exe. Но там ничего интересного не обнаружилось. Оказалось, что тот вызывает net1.exe с теми же параметрами (наверное, был в этом тайный смысл). А вот уже в коде net1.exe удалось найти вызов функции, которая отправляет сообщение – NetMessageBufferSend:
NET_API_STATUS NetMessageBufferSend( LPCWSTR servername, LPCWSTR msgname, LPCWSTR fromname, LPBYTE buf, DWORD buflen ); |
Здесь:
ПРИМЕЧАНИЕ Посылать сообщений с другого компьютера могут только администраторы! |
Чтобы просто "повторить" действия net send для отправки сообщения на некий компьютер, достаточно вызывать:
DWORD dwSize = 12; // Удвоенная длина строки "Hello!", т.к. все-таки уникод DWORD dwRet = NetMessageBufferSend(NULL, L"<CompName>", NULL, (LPBYTE)L"Hello!", dwSize); |
Такое "повторение" само по себе уже приятнее вызова ShellExecute, т.к. позволяет установить причину ошибки в случае отказа.
Но не только это хорошо, третий параметр функции (fromname) можно использовать в качестве имени отправителя! Стоит сразу оговориться, что произвольное имя должно быть зарегистрировано, для чего используется функция NetMessageNameAdd:
DWORD dwRet = NetMessageNameAdd(NULL, L"SenderName"); |
Здесь первый параметр аналогичен параметру servername, т.е. NULL для локального компьютера.
ПРИМЕЧАНИЕ Если регистрируется некое произвольное имя, то после того, как потребность в нем отпадет, его следует удалить из таблицы зарегистрированных имен функцией NetMessageNameDel. |
Отправка сообщения домену в принципе аналогична отправке сообщения на конкретный компьютер, за одним исключением. Предположим, что нужно отправить сообщение на домен «DOMAIN», тогда в качестве имени получателя нужно указать «DOMAIN*». Вот и вся хитрость.
Можно конечно, перебрать все компьютеры домена и послать каждому по сообщению (я даже где-то видел такую реализацию), но это же совсем не то, чего хочется, т.к. в качестве получателя будет имя компьютера получателя, а не имя домена. С другой стороны, каждый получатель будет думать, что сообщение отправляли именно ему и ничье самолюбие не будет задето. :)
ПРИМЕЧАНИЕ Справедливости ради стоит отметить, что "net send *" на самом деле перерабатывает внутри себя "звездочку" и подает на вход функции NetMessageBufferSend данные для отправки сообщения домену, а не "звездочке" :). |
NetSendSample – пример использования описанных выше возможностей. Все предельно просто: нужно заполнить нужные поля и нажать кнопку отправки. Обязательные поля: "Receiver", "Message", "Send to". Поле "Sender" заполнять не обязательно, если оно не заполнено, сообщение будет отправлено от имени локального компьютера.
Понятное дело, что вызов описанных выше функций - не единственное решение поставленной задачи, можно и поглубже копнуть (в некоторых случаях это действительно нужно), но для встраивания net send этого вполне достаточно. Дополнительные сведения можно получить на http://www.rsdn.ru/article/files/Progs/WinPopdown.xml.
Хочется надеяться, что изложенный выше материал будет если не интересен, то, по крайней мере, полезен тем программистам, которые ищут информацию по данной теме.
Сообщений 23 Оценка 41 [+0/-1] Оценить |