Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile

Development: Windows 10 UWP Wireless Label/Receipt Printer demo

3.57/5 (4 votes)
17 Aug 2016CPOL1 min read 9.1K  
Windows 10 UWP wireless label/receipt printer demo

As I already wrote the small demo apps for wireless printing of Label and Receipts for Android and Windows Phone 8, I now wrote such demo for Windows UWP. The application was tested on a Windows 10 Phone running Windows 10 Iot Enterprise Edition.

The code is based on the Windows Universal Sample app BTRFCommChat, but uses a different, single page layout.

layout_designer wp_ss_20160811_0001 wp_ss_20160811_0003 wp_ss_20160811_0005

The layout is based on a grid with a defined number of columns and rows. All rows are set to auto-adjust their height.

HTML
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

Then the grid columns contain stackpanels with GUI elements. To guide through the use of the demo application, these stackpanels are shown or hidden depending on the state of the demo. For example, the first state is to select a printer. In this state, only the “List Printers” button and the empty list is shown. After connecting a printer by tapping its name in the list, the stackpanel with “List Printers” and the list is collapsed (hidden).

As said, the code is based on the BTRFCommChat example. The first step was to change the BT service descriptor for the BT discovery to “RfcommServiceId.SerialPort”:

C#
// Find all paired instances of the Rfcomm service and display them in a list
dataServiceDeviceCollection = await DeviceInformation.FindAllAsync
                              (RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
if (dataServiceDeviceCollection.Count > 0)
{
 DeviceList.Items.Clear();
 foreach (var dataServiceDevice in dataServiceDeviceCollection)
 {
  DeviceList.Items.Add(dataServiceDevice.Name);
 }
 DeviceList.Visibility = Windows.UI.Xaml.Visibility.Visible;
}

When a device is tapped, the application tries to create a socket connection:

C#
try
{
 await dataSocket.ConnectAsync(dataService.ConnectionHostName, dataService.ConnectionServiceName);
 dataWriter = new DataWriter(dataSocket.OutputStream);
 Panel_SelectPrinter.Visibility = Visibility.Collapsed;
 PanelSelectFile.Visibility = Visibility.Visible;
 panelDisconnect.Visibility = Visibility.Visible;
 DataReader dataReader = new DataReader(dataSocket.InputStream);
 ReceiveStringLoop(dataReader);
}

Then a list of prepared demo print files is shown. The list is built from all files deployed with the application within the files folder:

C#
private async void FilesListbox_Loaded(object sender, RoutedEventArgs e)
{
 try
 {
  FilesListbox.Items.Clear();
  //fill the list with the files
  var folder = await StorageFolder.GetFolderFromPathAsync
               (Windows.ApplicationModel.Package.Current.InstalledLocation.Path + @"\files");
  IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
  foreach (StorageFile f in files)
   FilesListbox.Items.Add(f.Name);
 }
 catch (Exception ex)
 {
  System.Diagnostics.Debug.WriteLine("ListFiles: " + ex.Message);
 }
}

If the user selected a file and taps the “Print” button, the file is sent via the bluetooth socket connection to the printer:

C#
private async void SendFile()
{
 try
 {
  if (FilesListbox.SelectedIndex == -1)
   return;
  string filename = FilesListbox.SelectedItem.ToString();
  // fp3macklabel.prn
  // Open file in application package
  // needs to be marked as Content and Copy Always
  var fileToRead = await StorageFile.GetFileFromApplicationUriAsync
                   (new Uri("ms-appx:///files/" + filename, UriKind.Absolute));
  byte[] buffer = new byte[1024];
  int readcount = 0;
  using (BinaryReader fileReader = new BinaryReader(await fileToRead.OpenStreamForReadAsync()))
  {
   int read = fileReader.Read(buffer, 0, buffer.Length);
   while (read > 0)
   {
    readcount += read;
    Stream streamWrite = dataSocket.OutputStream.AsStreamForWrite();
    streamWrite.Write(buffer, 0, read);
    streamWrite.Flush();
    //the following does corrupt the byte stream!!!!!
    //byte[] buf = new byte[read];
    //Array.Copy(buffer, buf, read);
    //chatWriter.WriteBytes(buf);
    //await chatWriter.FlushAsync();
    //fileWriter.Write(buffer, 0, read);
    read = fileReader.Read(buffer, 0, buffer.Length);
   }
  }
  NotifyUser("sendFile " + readcount.ToString(), NotifyType.StatusMessage);
  await dataWriter.StoreAsync();
 }
 //catch hresult = 0x8000000e
 catch (NullReferenceException ex)
 {
  NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
  NotifyType.StatusMessage);
 }
 catch (IOException ex)
 {
  NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
  NotifyType.StatusMessage);
 }
 catch (Exception ex)
 {
  // TODO: Catch disconnect - HResult = 0x80072745 -
  // catch this (remote device disconnect) ex = {"An established connection was aborted
  // by the software in your host machine. (Exception from HRESULT: 0x80072745)"}
  NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
  NotifyType.StatusMessage);
 }
}

That’s it.

The source code available at github. The application has also been certified and is available in Windows Store.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)