/// <summary> /// Set the given mailslot's read timeout. /// </summary> /// <param name="readTimeout">Timeout for read operations in milliseconds. Set to uint.MaxValue for infinite timeout.</param> public static void SetMailslotTimeout(SafeMailslotHandle mailslotHandle, uint readTimeout) { if (!Imports.SetMailslotInfo(mailslotHandle, readTimeout)) { throw Errors.GetIoExceptionForLastError(); } }
/// <summary> /// Write a message to the specified mailslot /// </summary> /// <param name="hMailslot">Handle to the mailslot</param> /// <param name="lpszMessage">The message to be written to the slot</param> static void WriteMailslot(SafeMailslotHandle hMailslot, string message) { int cbMessageBytes = 0; // Message size in bytes int cbBytesWritten = 0; // Number of bytes written to the slot byte[] bMessage = Encoding.Unicode.GetBytes(message); cbMessageBytes = bMessage.Length; bool succeeded = NativeMethod.WriteFile( hMailslot, // Handle to the mailslot bMessage, // Message to be written cbMessageBytes, // Number of bytes to write out cbBytesWritten, // Number of bytes written IntPtr.Zero // Not overlapped ); if (!succeeded || cbMessageBytes != cbBytesWritten) { Console.WriteLine("WriteFile failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); } else { Console.WriteLine("The message \"{0}\" is written to the slot", message); } }
static void Main(string[] args) { SafeMailslotHandle hMailslot = null; try { // Try to open the mailslot with the write access. hMailslot = NativeMethod.CreateFile( MailslotName, // The name of the mailslot FileDesiredAccess.GENERIC_WRITE, // Write access FileShareMode.FILE_SHARE_READ, // Share mode IntPtr.Zero, // Default security attributes FileCreationDisposition.OPEN_EXISTING, // Opens existing mailslot 0, // No other attributes set IntPtr.Zero // No template file ); if (hMailslot.IsInvalid) { throw new Win32Exception(); } Console.WriteLine("The mailslot ({0}) is opened.", MailslotName); // Write messages to the mailslot. // Append '\0' at the end of each message considering the native C++ // Mailslot server (CppMailslotServer). WriteMailslot(hMailslot, "Message 1 for mailslot\0"); WriteMailslot(hMailslot, "Message 2 for mailslot\0"); Thread.Sleep(3000); // Sleep for 3 seconds for the demo purpose WriteMailslot(hMailslot, "Message 3 for mailslot\0"); } catch (Win32Exception ex) { Console.WriteLine("The client throws the error: {0}", ex.Message); } finally { if (hMailslot != null) { hMailslot.Close(); hMailslot = null; } } }
/// <summary> /// Get information for the given mailslot. /// </summary> public static MailslotInfo GetMailslotInfo(SafeMailslotHandle mailslotHandle) { MailslotInfo info = new MailslotInfo(); unsafe { if (!Imports.GetMailslotInfo( hMailslot: mailslotHandle, lpMaxMessageSize: &info.MaxMessageSize, lpNextSize: &info.NextSize, lpMessageCount: &info.MessageCount, lpReadTimeout: &info.ReadTimeout)) { throw Errors.GetIoExceptionForLastError(); } } return(info); }
public static extern bool ReadFile(SafeMailslotHandle handle, byte[] bytes, int numBytesToRead, out int numBytesRead, IntPtr overlapped);
public static extern bool WriteFile(SafeMailslotHandle handle, byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr overlapped);
public static extern bool GetMailslotInfo(SafeMailslotHandle hMailslot, IntPtr lpMaxMessageSize, out int lpNextSize, out int lpMessageCount, IntPtr lpReadTimeout);
/// <summary> /// Read the messages from a mailslot by using the mailslot handle in a call /// to the ReadFile function. /// </summary> /// <param name="hMailslot">The handle of the mailslot</param> /// <returns> /// If the function succeeds, the return value is true. /// </returns> static bool ReadMailslot(SafeMailslotHandle hMailslot) { int cbMessageBytes = 0; // Size of the message in bytes int cbBytesRead = 0; // Number of bytes read from the mailslot int cMessages = 0; // Number of messages in the slot int nMessageId = 0; // Message ID bool succeeded = false; // Check for the number of messages in the mailslot. succeeded = NativeMethod.GetMailslotInfo( hMailslot, // Handle of the mailslot IntPtr.Zero, // No maximum message size out cbMessageBytes, // Size of next message out cMessages, // Number of messages IntPtr.Zero // No read time-out ); if (!succeeded) { Console.WriteLine("GetMailslotInfo failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); return(succeeded); } if (cbMessageBytes == MAILSLOT_NO_MESSAGE) { // There are no new messages in the mailslot at present Console.WriteLine("No new messages."); return(succeeded); } // Retrieve the messages one by one from the mailslot. while (cMessages != 0) { nMessageId++; // Declare a byte array to fetch the data byte[] bBuffer = new byte[cbMessageBytes]; succeeded = NativeMethod.ReadFile( hMailslot, // Handle of mailslot bBuffer, // Buffer to receive data cbMessageBytes, // Size of buffer in bytes out cbBytesRead, // Number of bytes read from mailslot IntPtr.Zero // Not overlapped I/O ); if (!succeeded) { Console.WriteLine("ReadFile failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); break; } // Display the message. Console.WriteLine("Message #{0}: {1}", nMessageId, Encoding.Unicode.GetString(bBuffer)); // Get the current number of un-read messages in the slot. The number // may not equal the initial message number because new messages may // arrive while we are reading the items in the slot. succeeded = NativeMethod.GetMailslotInfo( hMailslot, // Handle of the mailslot IntPtr.Zero, // No maximum message size out cbMessageBytes, // Size of next message out cMessages, // Number of messages IntPtr.Zero // No read time-out ); if (!succeeded) { Console.WriteLine("GetMailslotInfo failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); break; } } return(succeeded); }
static void Main(string[] args) { SafeMailslotHandle hMailslot = null; try { // Prepare the security attributes (the lpSecurityAttributes parameter // in CreateMailslot) for the mailslot. This is optional. If the // lpSecurityAttributes parameter of CreateMailslot is NULL, the // mailslot gets a default security descriptor and the handle cannot // be inherited. The ACLs in the default security descriptor of a // mailslot grant full control to the LocalSystem account, (elevated) // administrators, and the creator owner. They also give only read // access to members of the Everyone group and the anonymous account. // However, if you want to customize the security permission of the // mailslot, (e.g. to allow Authenticated Users to read from and // write to the mailslot), you need to create a SECURITY_ATTRIBUTES // structure. SECURITY_ATTRIBUTES sa = null; sa = CreateMailslotSecurity(); // Create the mailslot. hMailslot = NativeMethod.CreateMailslot( MailslotName, // The name of the mailslot 0, // No maximum message size MAILSLOT_WAIT_FOREVER, // Waits forever for a message sa // Mailslot security attributes ); if (hMailslot.IsInvalid) { throw new Win32Exception(); } Console.WriteLine("The mailslot ({0}) is created.", MailslotName); // Check messages in the mailslot. Console.Write("Press ENTER to check new messages or press Q to quit ..."); string cmd = Console.ReadLine(); while (!cmd.Equals("Q", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("Checking new messages..."); ReadMailslot(hMailslot); Console.Write("Press ENTER to check new messages or press Q to quit ..."); cmd = Console.ReadLine(); } } catch (Win32Exception ex) { Console.WriteLine("The server throws the error: {0}", ex.Message); } finally { if (hMailslot != null) { hMailslot.Close(); hMailslot = null; } } }
public unsafe static extern bool SetMailslotInfo( SafeMailslotHandle hMailslot, uint lReadTimeout);
public unsafe static extern bool GetMailslotInfo( SafeMailslotHandle hMailslot, uint *lpMaxMessageSize, uint *lpNextSize, uint *lpMessageCount, uint *lpReadTimeout);
public static extern bool SetMailslotInfo([In] SafeMailslotHandle hMailslot, uint lReadTimeout);
/// <summary> /// Read the messages from a mailslot by using the mailslot handle in a call /// to the ReadFile function. /// </summary> /// <param name="hMailslot">The handle of the mailslot</param> /// <returns> /// If the function succeeds, the return value is true. /// </returns> static bool ReadMailslot(SafeMailslotHandle hMailslot) { int cbMessageBytes = 0; // Size of the message in bytes int cbBytesRead = 0; // Number of bytes read from the mailslot int cMessages = 0; // Number of messages in the slot int nMessageId = 0; // Message ID bool succeeded = false; // Check for the number of messages in the mailslot. succeeded = NativeMethod.GetMailslotInfo( hMailslot, // Handle of the mailslot IntPtr.Zero, // No maximum message size out cbMessageBytes, // Size of next message out cMessages, // Number of messages IntPtr.Zero // No read time-out ); if (!succeeded) { Console.WriteLine("GetMailslotInfo failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); return succeeded; } if (cbMessageBytes == MAILSLOT_NO_MESSAGE) { // There are no new messages in the mailslot at present Console.WriteLine("No new messages."); return succeeded; } // Retrieve the messages one by one from the mailslot. while (cMessages != 0) { nMessageId++; // Declare a byte array to fetch the data byte[] bBuffer = new byte[cbMessageBytes]; succeeded = NativeMethod.ReadFile( hMailslot, // Handle of mailslot bBuffer, // Buffer to receive data cbMessageBytes, // Size of buffer in bytes out cbBytesRead, // Number of bytes read from mailslot IntPtr.Zero // Not overlapped I/O ); if (!succeeded) { Console.WriteLine("ReadFile failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); break; } // Display the message. Console.WriteLine("Message #{0}: {1}", nMessageId, Encoding.Unicode.GetString(bBuffer)); // Get the current number of un-read messages in the slot. The number // may not equal the initial message number because new messages may // arrive while we are reading the items in the slot. succeeded = NativeMethod.GetMailslotInfo( hMailslot, // Handle of the mailslot IntPtr.Zero, // No maximum message size out cbMessageBytes, // Size of next message out cMessages, // Number of messages IntPtr.Zero // No read time-out ); if (!succeeded) { Console.WriteLine("GetMailslotInfo failed w/err 0x{0:X}", Marshal.GetLastWin32Error()); break; } } return succeeded; }