Mailslots in VB.NET?

J

Jim Lin

Has anyone successfully implemented a mailslot in VB.NET? The few examples
I've been able to find in VB are written in VB 6. Most of the examples I've
run across are written in C and about 10 years old.

I'm having difficulty getting the GetMailslotInfo call to give me useful
data (this might actually be a problem with CreateMailslot giving me a bogus
mailslot handle). CreateMailslot appears to be giving me a handle (it's not
giving me INVALID_HANDLE_VALUE).

Here's a code snippet from a little monitor program I whipped up to watch
for messages. Unfortunately, this half of the communications is normally
handled by a third party, so dumping mailslots in favor of some other mode
of communication is not possible.

Private Declare Function CreateMailslot Lib "kernel32" Alias
"CreateMailslotA" (ByVal lpName As String, ByVal nMaxMessageSize As Long,
ByVal lReadTimeout As Long, ByVal lpSecurityAttributes As
SECURITY_ATTRIBUTES) As Long
Private Declare Function GetMailslotInfo Lib "kernel32" (ByVal hfile As
Long, ByRef lpMaxMessageSize As Long, ByRef lpNextSize As Long, ByRef
lpMessageCount As Long, ByRef lpReadTimeout As Long) As Long

[...]

With sec
.bInheritHandle = False
.lpSecurityDescriptor = 0
.nLength = Len(sec)
End With

Debug.WriteLine("Creating handle to MailSlot")
Try
mailslotHandle = CreateMailslot(msName, 0, 0, sec)

'Check to see if a Mailslot was created successfully.
If mailslotHandle = INVALID_HANDLE_VALUE Then
Throw New Exception("Invalid handle value returned from
CreateMailSlot")
End If
Catch ex As Exception
'No mailslot available.
ErrorHandler("Mailslot not created", ex)
Exit Sub
End Try

'Main loop for the monitor.
Debug.WriteLine("Monitor starting")
While True = checkMail

'Read info about the mailslot. ***
System.NullReferenceException happening here ***
tmperr = GetMailslotInfo(mailslotHandle, maxsize,
msNextSize, msCount, msTimeout)

If (0 = tmperr) Then
tmperr = GetLastError()
Debug.WriteLine("Slot Info Error: " &
MessageText(tmperr))
skipTheRest = True
End If

[...]

Thanks for any help,
Jim
 
T

Tom Shelton

Has anyone successfully implemented a mailslot in VB.NET? The few examples
I've been able to find in VB are written in VB 6. Most of the examples I've
run across are written in C and about 10 years old.

I'm having difficulty getting the GetMailslotInfo call to give me useful
data (this might actually be a problem with CreateMailslot giving me a bogus
mailslot handle). CreateMailslot appears to be giving me a handle (it's not
giving me INVALID_HANDLE_VALUE).

Here's a code snippet from a little monitor program I whipped up to watch
for messages. Unfortunately, this half of the communications is normally
handled by a third party, so dumping mailslots in favor of some other mode
of communication is not possible.

A couple of suggestions - inline:


This declare is going to get you into trouble... The
SECURITY_ATTRIBUTES structure should be passed in ByRef - not by value.
The Longs should be changed to Integers since Longs in VB.NET are
64-bit - not 32 like in VB6. And you should probably loose the Alias
and change the declare type to Auto. And since the function returns a
handle - it should be declared to return type System.IntPtr.. See below.
Private Declare Function CreateMailslot Lib "kernel32" Alias
"CreateMailslotA" (ByVal lpName As String, ByVal nMaxMessageSize As Long,
ByVal lReadTimeout As Long, ByVal lpSecurityAttributes As
SECURITY_ATTRIBUTES) As Long

Here is the declare I would use...

<StructLayout(LayoutKind.Sequential)> _
Private Structure SECURITY_ATTRIBUTES
Public nLength As Integer
Public lpSecurityDescriptor As IntPtr
Public bInheritHandle As Boolean
End Structure

Private Declare Auto Function CreateMailslot Lib "kernel32" ( _
ByVal lpName As String, _
ByVal nMaxMessageSize As Integer, _
ByVal lReadTimeout As Integer) As IntPtr



Again, some of the same problems as above...
Private Declare Function GetMailslotInfo Lib "kernel32" (ByVal hfile As
Long, ByRef lpMaxMessageSize As Long, ByRef lpNextSize As Long, ByRef
lpMessageCount As Long, ByRef lpReadTimeout As Long) As Long

Private Declare Function GetMailslotInfo Lib "kernel32" ( _
ByVal hMailslot As IntPtr, _
ByRef lpMaxMessageSize As Integer, _
ByRef lpNextSize As Integer, _
ByRef lpMessageCount As Integer, _
ByRef lpReadTimeout As Integer) As Boolean
[...]

With sec
.bInheritHandle = False
.lpSecurityDescriptor = 0
.nLength = Len(sec)
End With

Dim mailSlotHandle As IntPtr

With Sec
.nLength = Marshal.SizeOf(sec)
.lpSecurityDescriptor =
.bInheritHandle = False
End With
Debug.WriteLine("Creating handle to MailSlot")
Try
mailslotHandle = CreateMailslot(msName, 0, 0, sec)

'Check to see if a Mailslot was created successfully.
If mailslotHandle = INVALID_HANDLE_VALUE Then
Throw New Exception("Invalid handle value returned from
CreateMailSlot")
End If

If IntPtr.opt_Explicit(mailslotHandle) =
INVALID_HANDLE_VALUE Then
...
End If
Catch ex As Exception
'No mailslot available.
ErrorHandler("Mailslot not created", ex)
Exit Sub
End Try

'Main loop for the monitor.
Debug.WriteLine("Monitor starting")
While True = checkMail

'Read info about the mailslot. ***
System.NullReferenceException happening here ***
tmperr = GetMailslotInfo(mailslotHandle, maxsize,
msNextSize, msCount, msTimeout)

If (0 = tmperr) Then
tmperr = GetLastError()
Debug.WriteLine("Slot Info Error: " &
MessageText(tmperr))
skipTheRest = True
End If

[...]

Thanks for any help,
Jim

Anyway, those are the things I would look at first... Oh, and by the way
- I hope that isn't a call to the API call GetLastError... If it is,
replace that with Marshal.GetLastWin32Error().

HTH,
Tom Shelton
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top