Windows IoT - Zebra Bluetooth Printer - printing

I have two Zebra Bluetooth Printers, a MZ220 and iMZ220. The "only" thing I would do, is to print text with a Windows IoT System on a Raspberry Pi 2. Nothing more ;)
Example:
Line1 " Hello World"
Line2 "---------------"
Line3 "Date:01.01.2016"
Line4 "Time: 18:00"
The USB Bluetooth Adapter BTA-403 from ORICO, I guess works well. With the Explorer I can connect to the Printer. But, what next? How do I connect to the Printer? How do I say to the Printer print "Hello World!"
Thanks!

These printers are using Bluetooth like a serial port aka SSP profile.
First, you'll have to edit your app manifest and add a new device capability
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="bluetooth.rfcomm">
<Device Id="any">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>
</Capabilities>
You can get the paired printers like this
var devices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
Once you identified the right printer, you can open the connection
var service = await RfcommDeviceService.FromIdAsync(DeviceInfo.Id);
var socket = new StreamSocket();
await socket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName);
You should be able to send then information like this
private async void PrintAsync(string line)
{
var writer = new DataWriter(socket.OutputStream);
var command = "^XA^LH30,30^F020,10^AD^FD + line + "^FS^XZ";
writer.WriteString(command);
await writer.StoreAsync();
}

Related

Edit Default Printer Preferences Job Type with VBScript

I am trying to edit a machines default printer preferences. More specifically, I am trying to change each print type into a locked print, and then assign a username and password to each individual user:
Everyone is on the PCL6 printer drivers but I have no idea how to access this from within VBScript. Here is what I have so far. I have been annotating it as much as I can so hopefully whoever picks this up if I leave will be able to understand it. All is in working order:
Option Explicit
' Tell WSH to resume on errors, otherwise our error handling can't do it's job
On Error Resume Next
' Define variables
Dim objNetwork, objWMIService, objPrinter
Dim colInstalledPrinters
Dim strPrinterServer, strPrinterShare, strUserName, strPassword, strPrinterName
Dim Return, LocalDefault
Dim DynamicMessage
Dim DefaultPrinter
strPrinterServer = "\\GBDSCWSSC0125"
strPrinterShare = "GBGBMIL1NPSC000"
strPassword = "1234"
msgbox("This tool will set up your default printer with a username and password. When changing default printers, please run this tool again")
strUserName = CreateObject("WScript.Network").UserName
DynamicMessage = msgbox("Your username is " & strUserName & vbNewLine & "Is this correct?", vbYesNo)
If DynamicMessage = vbNo Then
strUserName = InputBox("Please enter your username")
DynamicMessage = msgbox("Your username is " & strUserName, vbOK)
End If
' Get WMIService so we can run WMI queries (windows management instrumentation). Basically a library for controlling windows
Set objWMIService = GetObject( _
"winmgmts:" & "{impersonationLevel=impersonate}!\\" _
& strComputerName & "\root\cimv2")
' Run a WMI query to get all the installed printers. This returns a collection so the variable uses the "col" prefix
Set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
' The WMI query returns a collection that we need to loop through and check to see if the current printer object is the default printer
For Each objPrinter in colInstalledPrinters
If objPrinter.Default = "True" Then
If objPrinter.Name <> "Microsoft Office Document Image Writer" Then
LocalDefault = True
strPrinterName = objPrinter.Name
DynamicMessage = msgbox("Default printer is " & strPrinterName, vbOKOnly)
End If
End If
Next
msgbox("Done!")
Set objWMIService = Nothing
Set objNetwork = Nothing
WScipt.Quit
Is this at all possible?
You can try setting registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\printername\PrinterDriver‌​Data\capsdb_scope::U‌​I_Customize on print server with this value:
<?xml version="1.0" encoding="utf-8"?>
<rcf version="1.0">
<devicesettings drivername="RICOH MP 402SPF PCL 6" independent="yes">
<item name="userid_type" value="windowsloginname"/>
<item name="jobtype" value="lockedprint"/>
</devicesettings>
<featurelock>
<item fixvalue="windowsloginname" name="userid_type"/>
<item fixvalue="lockedprint" name="jobtype"/>
</featurelock>
<popupbeforeprint type="jobtype">
<item defaultstring="default" name="username"/>
<item defaultstring="blank" name="password"/>
<item defaultstring="default" name="userid"/>
</popupbeforeprint>
</rcf>

Trying to connect to Ticket Printer using VB6 Winsock

I am trying to send data from a VB6 program to a ticket printer Via TCP/IP. The only VB6 way I have found to try and do this is using the WinSock Control.
I use the following code to connect
WinSock.Protocol = sckTCPProtocol
WinSock.RemoteHost = txtIPAddress.Text
WinSock.RemotePort = txtPort.Text
WinSock.Connect
And then try and send the data as follows
WinSock.SendData ("<F8>" & txtPrint.Text & "<p>")
Everytime I try and do this, it fails because the Winsock.State is 6 (Connecting). This just stays at connecting and never connects or fails. I am able to connect to the printer using this IP/Port combo outside of VB6. Is there anything I may be doing wrong? Can the WinSock control do this?
In a .net program provided, this seems to be accomplished by doing the following:
CONNECT
client = new TcpClient(ip_address, 9100);
s = client.GetStream(); //s is System.Net.Sockets.NetworkStream
s.ReadTimeout = 500; //attempt to read for up to 0.5 seconds
sr = new StreamReader(s); //create read stream
sw = new StreamWriter(s); //create write stream
sb = new BinaryWriter(s); //create binary stream
sw.AutoFlush = true; //set write stream to flush data when < full buffer
SEND:
sw.WriteLine(command);
Thank you.
You are missing up concepts. I remember this from 15 years ago.
Winsock is for work with a protocol. You must know the printer protocol. Is not just sample text.

Batch printing PDF files on Ricoh MP 4000 printer using Ghostscript without Adobe

I have a requirement to Print a bunch of existing PDF files every day to a network Ricoh MP 4000 Printer. I need to print these using "HoldPrint" job type option. I am able to print it directly but I want it to do a hold print which does not mix up with other user's printing. I am using GhostScript 9.10
The one that directly prints (through function call from "Maciej"'s post):
" -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -qQUIET -sjobtype=holdprint -suserid=abc -dNumCopies=1 -sDEVICE=ljet4 -sOutputFile=\"\\spool\PrinterName\" \"C:\Printing\mypdffile.pdf\" "
Looks like I am overwriting the jobtype switch but not sure how to get it.
I tried different combinations but it simply does not work. Any help is greatly appreciated.
-dPrinted -dBATCH -dNOPAUSE -dNumCopies=1 -sDEVICE=ljet4 -sOutputFile=%printer%printerName "C:\Printing\mypdffile.pdf"
Update: Here is the version that worked for me.
/*
* Printer used: Ricoh Aficio MP 4000
* Purpose: To print PDF files as a scheduled job to a network printer.
* The files will be queued under a specific user id.
* The user prints the files under his account.
* Pre-requisite: Install the network printer on the job server
* Manually configure Printer Job settings with user id
* and Job type set to "Hold Print"
*/
string _sourceFolder = “PDFFilesFolderPath”;
DirectoryInfo di = new DirectoryInfo(_sourceFolder);
var files = di.GetFiles().OrderBy(f => f.Name);
string _printer = "BMIS"; // Printer name as seen in the Devices and Printers section
foreach (var f in files)
{
PrintPDF(#"C:\Program Files\gs\gs9.10\bin\gswin32c.exe", 1, _printer, f.FullName);
}
/// <summary>
/// Print PDF.
/// </summary>
/// <param name="ghostScriptPath">The ghost script path. Eg "C:\Program Files\gs\gs9.10\bin\gswin32c.exee"</param>
/// <param name="numberOfCopies">The number of copies.</param>
/// <param name="printerName">Exact name of the printer as seen under Devices and Printers.</param>
/// <param name="pdfFileName">Name of the PDF file.</param>
/// <returns></returns>
public bool PrintPDF(string ghostScriptPath, int numberOfCopies, string printerName, string pdfFullFileName )
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = " -dPrinted -dNoCancel=true -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=" + Convert.ToString(numberOfCopies) + " -sDEVICE=mswinpr2 -sOutputFile=%printer%" + printerName + " \"" + pdfFullFileName + "\"";
startInfo.FileName = ghostScriptPath;
startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process process = Process.Start(startInfo);
process.WaitForExit(30000);
if (process.HasExited == false) process.Kill();
return process.ExitCode == 0;
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error);
throw;
}
}
Ghostscript doesn't have a 'jobtype' switch, nor a suserid switch, so its not surprising that they have no effect. Possibly the post you reference has some more information, but I can't find any such post, maybe you can point to it (URL)
[later]
Setup.ps needs to be a PostScript file (because that's what Ghostscript understands, its a PostScript interpreter). From the documentation you want to set DocumentName, which is a member of the User Settings dictionary, so:
mark
/UserSettings <<
/DocumentName (My name goes in here)
>>
(mswinpr2) finddevice
putdeviceprops
setdevice
The white space is just for clarity. This is lifted pretty much verbatim from the example.
So, you need to modify the 'setup.ps' you send for each job. You can either write a custom setup.ps for each one, or use the 'PostScript input' capability of GS and supply the whole content of setup.ps on the command line using the -c and -f switches. All setup.ps does is run the PostScript in there before you run your own PostScript program (assuming you put setup.ps before your PostScript program on the command line).
This is pretty nasty actually, its not the way devices are normally configured, but the mswinpr2 device was originally written by someone outside the Ghostscript team, and presumably adopted wholesale.

Very slow Network printing using PrintServer and PrintQueue

I am working on an ASP.NET application and need to send documents to a network printer. I have utilized the PrintServer and PrintQueue to achieve the purpose as follows:
using System.Printing;
private void PrintTicket
{
var server = "Network Server Name";
var filePath = "File to Print";
var printer = "Network Printer Name";
var printerServer = new PrintServer(String.Format(#"\\{0}", server));
var printQueue = printerServer.GetPrintQueue(printer);
printQueue.AddJob("New Printing Job", filePath, false);
}
The network printer can be found and the print job is executed.
However, the performance is very slow. It took 5-10 seconds to start printing when method printQueue.AddJob() is executed.If the printer is connected to my local machine, there is no performance issue at all.
Any suggestions? Thanks in advance.
Instead of using PrintQueue class you can simply use File.Copy(filePath, printerDestination, true);
I have tried both the options i.e. using printqueue as well as file copy and file copy is much faster compare to using printqueue class.
Thanks,
Arnab

Flash Media Server & AS3: Publishing works, recording doesn't

I'm currently having an issue with FMS4 developer edition on both Linux (x64) and Windows XP (x86).
When I stream a webcam using ns.publish("foobar", "live") I can watch the live stream on another client, however when i use ns.publish("foobar", "record"); neither broadcasting nor recording works.
Using the "live" parameter the client appears in the log files and in the administration console as "publishing", using "record" the client appears as "idle".
Is there anything I need to configure besides LIVE_DIR in fms.ini?
Is this a restriction in the developer edition?
Is there something else I'm missing?
Here is the relevant part of the code (condensed):
var camLive:Camera = Camera.getCamera();
var nc:NetConnection = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
var ns:NetStream;
nc.connect("rtmp://192.168.1.63/live/");
function netStatusHandler(event:NetStatusEvent):void {
if (event.info.code == "NetConnection.Connect.Success") {
ns = new NetStream(nc);
ns.attachCamera(camLive);
ns.publish("foobar", "record");
}
}
Thanks in advance!
Fabian
The problem is the live application. You can create an empty folder inside "applications", call it "test", then stream to "rtmp://192.168.1.63/test" with parameter "record". According to forums.adobe.com/thread/827134?tstart=0

Resources