|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Network Services WriteFile: Broadcasting System Messages using Mailslots |
||
Posted: | Thursday October 10. 2002 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6 | |
Developed with: | VB6, Windows XP | |
OS restrictions: | None | |
Author: | VBnet - Randy Birch | |
Related: |
NetMessageBufferSend: Broadcasting System Messages | |
Prerequisites |
None. This code will broadcast to, and can be run on, both 9x and NT-based systems. To receive broadcasts on 9x/ME, WinPopup must be running. |
|
Where
system admins had wanted to send system-wide broadcasts of alert
notifications to other computers (ala Net Send), VBnet has up till
now only offered the NT-based NetMessageBufferSend solution. This page details another method that does exactly the same thing as NetMessageBufferSend. But unlike NetMessageBufferSend: Broadcasting System Messages this method uses APIs and functionality native to all versions of Windows - the code here can be run on a 95, 98, ME, NT, 2000, XP or .Net server system to send messages to any other system. However, in order to receive the messages on 9x, the WinPopup must be running. Mailslots are used for interprocess communications -- mailslots broadcast messages within a domain. If several processes in a domain each create a mailslot using the same name, every message that is addressed to that mailslot and sent to the domain is received by the participating processes. Because one process can control both a server mailslot handle and the client handle retrieved when the mailslot is opened for a write operation, applications can easily implement a simple message-passing facility within a domain. This makes it possible to use mailslots created with VB to allow an application running on one machine to communicate directly with an application (or applications) on the same machine or on other machines across the network. But in addition to the interprocess functionality, a mailslot can also be used to transmit a message to the user on a specific machine, a group of machines, or the entire domain, by formatting the message appropriately. Such messages are transmitted to the default system mailslot and are displayed to the user as a system-modal message box. And unlike mailslot interprocess communication applications that utilize CreateMailslot, broadcasting a machine-to-machine message can easily be performed using CreateFile, WriteFile and CloseHandle. But note: ... no file is actually created; a mailslot is a pseudofile; it resides in memory, and you use standard file functions to access it. Unlike disk files, however, mailslots are temporary -- when all handles to a mailslot are closed, the mailslot and all the data it contains are deleted. The Message From field can contain any string that indicates the sender. The Send To variable contains either a specific machine name, or * to send to all active machines on the domain. The Message sent is restricted to 128 characters. This demo was created on Windows XP and tested by broadcasting messages to XP and Windows 2000 machines. Through reader reports I can now confirm that while this code can be executed successfully on both 9x-based and NT-based systems, 9x systems still require WinPopup running in order to receive the messages. |
BAS Module Code |
None. |
|
Form Code |
Start a new project with three text boxes (Text1-Text3 (Text3 is multiline in this demo)), a command button (Command1) and a label (Label1) to display the returned message. Other ID labels for the form are optional. Add the following to the form: |
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private Const OPEN_EXISTING = 3 Private Const GENERIC_WRITE = &H40000000 Private Const FILE_SHARE_READ = &H1 Private Const FILE_ATTRIBUTE_NORMAL = &H80 Private Const vbDotEveryone As String = "*" 'User-defined type for passing 'the data to BroadcastMessage Private Type MailslotMessageData sMsgFrom As String sSendTo As String sMessage As String End Type Private Declare Function CreateFile Lib "kernel32" _ Alias "CreateFileA" _ (ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, _ ByVal lpSecurityAttributes As Long, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long Private Declare Function WriteFile Lib "kernel32" _ (ByVal hFile As Long, _ ByVal lpBuffer As Any, _ ByVal nNumberOfBytesToWrite As Long, _ lpNumberOfBytesWritten As Long, _ ByVal lpOverlapped As Long) As Long Private Declare Function CloseHandle Lib "kernel32" _ (ByVal hHandle As Long) As Long Private Sub Form_Load() Text1.Text = "Systems Database Administrator" Text2.Text = "*" With Text3 .MaxLength = 128 .Text = "An unscheduled maintenance requirement " & _ "will take the database offline beginning " & _ vbNewLine & _ "6:00 pm Friday, resuming at 8:00 am Sunday." End With Command1.Caption = "Send Message" End Sub Private Sub Command1_Click() Dim msg As MailslotMessageData 'fill the structure with the 'message data With msg .sMsgFrom = Text1.Text .sSendTo = Text2.Text .sMessage = Text3.Text End With 'return the success to a label Label1.Caption = BroadcastMessage(msg) End Sub Private Function BroadcastMessage(msg As MailslotMessageData) As String Dim hFile As Long Dim byteswritten As Long Dim buff As String Dim sSlotName As String 'ensure message type has data 'and either abort transmission 'or set default values If Len(msg.sMessage) = 0 Then BroadcastMessage = "No message specified; nothing to do." Exit Function End If If Len(msg.sSendTo) = 0 Then msg.sSendTo = vbDotEveryone End If If Len(msg.sMsgFrom) = 0 Then msg.sMsgFrom = "Mailslot System Message" End If 'must be something to do, so... 'the mailslot name is a combination of 'the receiving machine name prefixed 'with double slashes, followed by '\mailslot\messngr sSlotName = "\\" & msg.sSendTo & "\mailslot\messngr" 'the message transmitted is a 'combination of the from, to and 'message strings separated by null 'characters buff = msg.sMsgFrom & vbNullChar & _ msg.sSendTo & vbNullChar & _ msg.sMessage & vbNullChar & vbNullChar 'obtain a handle to the mailslot hFile = CreateFile(sSlotName, _ GENERIC_WRITE, _ FILE_SHARE_READ, _ 0&, _ OPEN_EXISTING, _ FILE_ATTRIBUTE_NORMAL, _ 0&) 'if it's a go ... If hFile <> 0 Then 'write the message to the slot and close the file If WriteFile(hFile, _ buff, _ Len(buff), _ byteswritten, _ 0) <> 0 Then If (Len(buff) = byteswritten) Then BroadcastMessage = "The message was successfully sent." Else BroadcastMessage = "Message sent but bytes written <> message size." End If 'If (Len(buff) Else BroadcastMessage = "Error writing the message." End If 'If WriteFile Call CloseHandle(hFile) End If 'If hFile End Function |
Comments |
The code will populate Text1, 2 and 3 with
test information.
Note --- if you are on a domain, do not test this routine with the * in the To box ... everyone will get the alert!! No pre-send warning or confirmation is displayed ... as soon as WriteFile is called the alerts appear. Note as well that when an alert is sent to all machines (*), the alert also appears on the sending machine as well. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |