// --------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// --------------------------------------------------------------------
namespace TestLargeMessageQueue
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Messaging;
using Microsoft.Samples.MessageQueuing.LargeMessageQueue;
using System.IO;
using Microsoft.Win32;
using System.Globalization;
///
/// Interaction logic for Window1.xaml
///
public partial class Window1 : Window
{
// Handle for the send/receive queue
MessageQueue queue;
public Window1()
{
InitializeComponent();
// Initializing all the required values
progressBarSend.Visibility = Visibility.Hidden;
progressBarReceive.Visibility = Visibility.Hidden;
textFileName.Clear();
textFileName.Text = Directory.GetCurrentDirectory() + @"\" + "default.bmp";
// Set the fragment size to 10KB
textFragmentSize.Clear();
textFragmentSize.Text = "10000";
// The queue can be public or private queue
String queuePath = @".\private$\largemessageq";
// Must be same as Parameters.STATUS_QUEUE in the LargeMessageQueue project
String statusQueuePath = @".\private$\statusq";
// Flag to create transactional queue
bool transactional = true;
// Delete and create both the queues
try
{
MessageQueue.Delete(queuePath);
}
catch (MessageQueueException)
{
// Don't do anything. Queue already not present
}
try
{
MessageQueue.Delete(statusQueuePath);
}
catch (MessageQueueException)
{
// Don't do anything. Queue already not present
}
try
{
queue = MessageQueue.Create(queuePath, transactional);
MessageQueue.Create(statusQueuePath, transactional);
}
catch (MessageQueueException mqe)
{
MessageBox.Show("Error: " + mqe.Message, "Error!");
}
this.SetQueueViewerStatus();
}
// Reinitializes the objects being used
private void labelClearObject_MouseDown(object sender, MouseButtonEventArgs e)
{
textFileName.Clear();
textFileName.BorderBrush = Brushes.LightBlue;
imageSendFile.Visibility = Visibility.Hidden;
imageReceiveFile.Visibility = Visibility.Hidden;
progressBarSend.Visibility = Visibility.Hidden;
progressBarReceive.Visibility = Visibility.Hidden;
labelFileSize.Background = Brushes.Transparent;
this.SetQueueViewerStatus();
}
// Clears the fragment size text box
private void labelClearFragment_MouseDown(object sender, MouseButtonEventArgs e)
{
textFragmentSize.Clear();
textFileName.BorderBrush = Brushes.LightBlue;
}
// Use normal Send
private void buttonSendNormal_Click(object sender, RoutedEventArgs e)
{
this.SendGeneric(false);
}
// Use large message sample API
private void buttonSend_Click(object sender, RoutedEventArgs e)
{
this.SendGeneric(true);
}
// Do lossy receive. The first message will be destructively received and thus holes in the large message sequence is simulated
private void buttonLossyReceive_Click(object sender, RoutedEventArgs e)
{
this.ReceiveGeneric(true);
}
// Do complete receive without simulating holes
private void buttonReceive_Click(object sender, RoutedEventArgs e)
{
this.ReceiveGeneric(false);
}
// Open file dialog operation
private void buttonFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "BMP Image files (*.bmp)|*.bmp";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
Nullable dialogResult = openFileDialog.ShowDialog();
if (dialogResult == true)
{
textFileName.Text = openFileDialog.FileName;
}
}
// Populate sender side image viewer and file size (less than or greater than 4MB) indicator
private void textFileName_TextChanged(object sender, TextChangedEventArgs e)
{
// Check the validity of the file name entered in the text box as it is typed
if (this.IsValidBmpFile(textFileName.Text))
{
FileInfo fileInfo = new FileInfo(textFileName.Text);
float size = (float)(fileInfo.Length) / 1000000;
labelFileSize.Content = size.ToString() + "MB";
if (fileInfo.Length > 4000000)
{
labelFileSize.Background = Brushes.LightBlue;
}
else
{
labelFileSize.Background = Brushes.LightGreen;
}
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.UriSource = new Uri(textFileName.Text);
bmpImage.EndInit();
imageSendFile.Source = bmpImage;
textFileName.BorderBrush = Brushes.Green;
imageSendFile.Visibility = Visibility.Visible;
}
else
{
textFileName.BorderBrush = Brushes.Red;
imageReceiveFile.Visibility = Visibility.Hidden;
labelFileSize.Content = string.Empty;
labelFileSize.Background = Brushes.Transparent;
}
}
// Handles both normal and large message send operations
private void SendGeneric(bool useLargeMessageSample)
{
progressBarReceive.Visibility = Visibility.Hidden;
Utilities.StartProgressBar(progressBarSend);
try
{
MessageQueueTransaction transaction = new MessageQueueTransaction();
transaction.Begin();
IMessageFormatter formatter = new BinaryMessageFormatter();
Message message = new Message();
FileInfo fileInfo = new FileInfo(textFileName.Text);
FileStream fStream = fileInfo.OpenRead();
byte[] b = new byte[fStream.Length];
fStream.Read(b, 0, b.Length);
MemoryStream mStream = new MemoryStream(b, 0, b.Length, false);
message.Label = fileInfo.Name;
message.Formatter = formatter;
message.UseDeadLetterQueue = true;
message.Body = mStream;
int fragmentSize = 0;
if (textFragmentSize.Text.Length != 0)
{
fragmentSize = Int32.Parse(textFragmentSize.Text, CultureInfo.InvariantCulture);
}
if (useLargeMessageSample)
{
LargeMessageQueue largeMessageQueue = new LargeMessageQueue(this.queue, fragmentSize);
largeMessageQueue.Send(message, transaction);
}
else
{
this.queue.Send(message, transaction);
}
transaction.Commit();
Utilities.StopProgressBar(progressBarSend);
this.SetQueueViewerStatus();
MessageBox.Show("Send successful!", "Success!");
}
catch (Exception ex)
{
Utilities.ErrorProgressBar(progressBarSend);
this.SetQueueViewerStatus();
MessageBox.Show("Send Error: " + ex.Message, "Error!");
}
}
// Handles both lossy and non-lossy large message receive operations
private void ReceiveGeneric(bool isLossy)
{
progressBarSend.Visibility = Visibility.Hidden;
Utilities.StartProgressBar(progressBarReceive);
try
{
MessageQueueTransaction transaction = new MessageQueueTransaction();
transaction.Begin();
if (isLossy)
{
this.queue.Receive(new TimeSpan(0, 0, 10));
}
LargeMessageQueue largeMessageQueue = new LargeMessageQueue(this.queue, 0);
System.Messaging.Message message = largeMessageQueue.Receive(new TimeSpan(0, 0, 10), transaction);
// Redundant. Will never execute these for lossy receive
message.Formatter = new BinaryMessageFormatter();
MemoryStream mStream = (MemoryStream)message.Body;
string newLabel = "Received - " + message.Label;
FileStream fStream = new FileStream(newLabel, FileMode.Create, FileAccess.ReadWrite);
mStream.WriteTo(fStream);
mStream.Close();
fStream.Close();
transaction.Commit();
this.LoadImageFile(imageReceiveFile, newLabel);
imageReceiveFile.Visibility = Visibility.Visible;
Utilities.StopProgressBar(progressBarReceive);
this.SetQueueViewerStatus();
MessageBox.Show("Receive successful!", "Success!");
}
catch (LargeMessageQueueException lmqe)
{
Utilities.ErrorProgressBar(progressBarReceive);
imageReceiveFile.Visibility = Visibility.Hidden;
this.SetQueueViewerStatus();
MessageBox.Show("Receive Error: " + lmqe.Message + "\n Large Sequence Id:" + lmqe.CorrelationId, "Error!");
}
catch (Exception ex)
{
Utilities.ErrorProgressBar(progressBarReceive);
imageReceiveFile.Visibility = Visibility.Hidden;
this.SetQueueViewerStatus();
MessageBox.Show("Receive Error: " + ex.Message, "Error!");
}
}
// Handles Drop Event on the window for files.
private void DropFile(object sender, DragEventArgs e)
{
textFileName.Clear();
string[] fileNames = e.Data.GetData(DataFormats.FileDrop, true) as string[];
string fileName = fileNames[0];
try
{
FileInfo fileInfo = new FileInfo(fileName);
textFileName.Text = fileName;
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file: " + ex.Message);
}
// Mark the event as handled so that the default handler is not used
e.Handled = true;
}
// Get the message count in the queue
private int GetMessageCount()
{
List messageList = new List();
try
{
// there is no messagequeue.count or .length
// this is pretty much the only reliable (and ugly) way of getting
// the number of messages in a queue
Message message = this.queue.Peek(TimeSpan.Zero);
while (true)
{
if (message == null)
{
break;
}
messageList.Add(message);
message = this.queue.PeekByLookupId(MessageLookupAction.Next, message.LookupId);
}
}
catch (MessageQueueException)
{
// Don't do anything
}
catch (InvalidOperationException)
{
// Don't do anything
}
return messageList.Count;
}
// Loads the bmp image into the image viewer
private void LoadImageFile(Image image, string label)
{
string fileName = Directory.GetCurrentDirectory() + @"\" + label;
if (this.IsValidBmpFile(fileName))
{
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.UriSource = new Uri(fileName);
bmpImage.EndInit();
image.Source = bmpImage;
}
else
{
image.Visibility = Visibility.Hidden;
}
}
// Check if the file selected is a valid bmp file
private bool IsValidBmpFile(string fileName)
{
try
{
FileInfo fileInfo = new FileInfo(fileName);
if (fileInfo.Exists)
{
if (string.Compare(fileInfo.Extension, 0, ".BMP", 0, fileInfo.Extension.Length, StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
catch (Exception)
{
return false;
}
}
// Changes the color and content of the queue viewer
private void SetQueueViewerStatus()
{
int queueMessageCount = this.GetMessageCount();
if (queueMessageCount != 0)
{
labelQueueViewer.Background = Brushes.LightGreen;
labelQueueViewer.Content = queueMessageCount + " messages";
}
else
{
labelQueueViewer.Background = Brushes.PaleVioletRed;
labelQueueViewer.Content = "Empty";
}
}
}
}