Development: Windows 10 UWP Wireless Label/Receipt Printer demo
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.
The layout is based on a grid with a defined number of columns and rows. All rows are set to auto-adjust their height.
<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 stackpanel
s 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
”:
// 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:
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:
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:
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.