Open TonyHenrique opened 4 years ago
A separate capability for this would be good because it makes it clear that this is a special scenario, should be treated differently, and is probably not for everybody.
Even with this setting/capability I still think there's value in the user having to opt-in to silent printing through the UI once. This will avoid any app from surprising users by printing without ever showing any UI indicating that it wants to print. This would be comparable with requesting location or other potentially sensitive information that the user may not want.
This should also be an app level setting that can be revoked in future if the user desires.
For scenarios like kiosks that need to print and not desktop style apps that are more likely to be used by a single person for longer, such devices/apps still need initial configuration which would include testing the printer configuration and therefore enabling this setting.
It could be a permission that only presents it's permission dialog on the first programmatic print - rather than just at install, or first run of the app.
I suppose that this will be useful to enable to use Windows10X with UWP instead of Win32, for those scenarios.
I also sent a message about this to Stefan Wick, he said: ... Not a WinUI limitation, but a limitation of the appmodel you chose. When you build a WinUI app with Win32 appmodel it will work, but not with UWP appmodel. https://twitter.com/StefanWickDev/status/1240099309204287488
But anyways, I believe that the WinUI team can redirect this request, as this is required to increase the success of the WinUI, allowing it to be used in more scenarios, like the ones that I described.
@TonyHenrique IMO you are correct in posting this issue here even if it's not directly WinUI related. There is just no other platform out there right now to discuss UWP app model/WinRT improvements and where we can be confident at least someone from MS will take a look at it and redirect it internally if required (yes, MS keeps repeating they listen to feedback even in the feedback hub but the perception of the feedback hub among the community is really bad). The WinUI team recognizes this feedback platform issue and thus tolerates community input discussing (fundamental) UWP issues.
I know this is further out of scope, but it may be worth looking at a possible opt in permission system for WinUI Desktop. Giving the user peace of mind, without the Win32 free for all, and less restrictive than UWP.
Either creating new sets of permissable actions, or a way to detect if an action could be abused, and display a general "Are you sure you want to do XXXX" permission. With Just Once Always and Never options.
@takashi-moriyama as FYI
This is very similar to existing issue #52, but has more detail. @awsomecode would you mind if we made this the primary since it has the "proposal" format with details? What else would you want to add to the proposal?
@jonwis Ya, this one will cover my requirement as well. You can make this primary.
@TonyHenrique FYI we do not show consent prompts on install[1]; we show them on first-use (more correctly: the first time the app requests the permission, which might be before it actually "uses" it, depending on how the app is written and the specific API in question). Otherwise, agreed that this feature would need a permission that the user could consents to and can later change their mind in Settings.
[1] We do perform a UAC prompt for anything that impacts the machine / other users during install.
Moving to backlog for future potential feature work.
@stevewri This wont be available on WinUI3 ?
This wont be available on WinUI3 ?
Printing without confirmation requires work at the security / isolation level, not just the UI level.
This is so much import for retail softwares. Without this we can't convert WPF apps to UWP/WinUI3
@AwsomeCode You should be able to print without a UI confirmation dialog if you will port your WPF apps to WinUI 3 desktop apps. @ptorr-msft's comment is about (WinUI 3) UWP apps (since the requested change will require changes in the UWP app model implementation and that's not something WinUI is responsible for).
I'm trying to build a POS application with UWP, can't get the POS to recognize the cheaper thermal printers out there, I'm waiting on this to be realeased so I can properly deal with the printers that are not supported by the POS namespace.
@Rothanan can you share the details of the printers that don't work? Are they specifically sold as POS devices that adhere to the POS standards?
@ptorr-msft this are the few I have tried. https://www.atpos.in/product/atpos-usb-bluetooth-e-200-portable-thermal-receipt-printer/ https://www.atpos.in/product/atpos-hop-h58-58mm-thermal-receipt-printer/
Surprisingly they work with Android. But not with UWP.
I wonder how macOS deal with such issue. Is there a "print permission", or apps are allowed to print without confirm?
@ptorr-msft they are very basic printers, they only work through ESC/POS. I can get them working on android, but not in UWP:
Here's a model: https://www.amazon.com/Wireless-Bluetooth-MUNBYN-Portable-Compatible/dp/B07N86DR4J
They are sold mainly as mobile bluetooth thermal printers(they also come with an usb conection) and because they are cheaper most customers wanna buy and use them.
POS printers, sounds like an IOT device situation, and that supports device drivers right? Which would allow direct talking to the printer device right?
Yeah, you're right, in android devices, all I do is send ESC/POS commands directly to the printer.
I'm looking for a way to do the same in UWP, in a Desktop environment.
@Rothanan thanks for the info; I will send to the POS team internally to see if they know of any issues with these devices.
@ptorr-msft any update from pos team?
Sorry @AwsomeCode , some rather urgent personal stuff came up and I've been distracted. Tracking them down now and will pass along. Thanks for the reminder.
Sorry to bother, but, any news on this?
Can you confirm if you are using the POS APIs or the regular printing APIs?
In UWP Its not POS APIs or Regular Printing API. I have tried RawPrint Which sends RAW ESC/POS data commands to printer and it print silently on printer. It works in debug mode. But on published app its not allowed. For published app we have to use Desktop Extension for UWP. Which is not best experience in development. (Our UWP app never get approved in store. They say its crashing and In our machines its working fine.)
In Android Sending RAW ESC/POS data commands via Bluetooth and its gets print silently.
In iOS Printer is not getting connected via Bluetooth.
Below are the printers I am referring to. https://www.atpos.in/product/atpos-usb-bluetooth-e-200-portable-thermal-receipt-printer/ https://www.atpos.in/product/atpos-hop-h58-58mm-thermal-receipt-printer/
I have tried RawPrint Which sends RAW ESC/POS data commands to printer and it print silently on printer. It works in debug mode. But on published app its not allowed.
That project says it relies on .NET 4, which isn't supported for UWP apps (only .NET Native is supported). Can you pair the printers first and then use the POS API?
I have tried this sample project it did not worked. https://docs.microsoft.com/en-us/samples/microsoft/windows-universal-samples/posprinter/
Can you confirm if you are using the POS APIs or the regular printing APIs?
I tried using the POS API, it doesn't recognize the ESC/POS printer, the POS API support very few printers which renders it unusable.
We are just looking for a away to send ESC/POS commands to ANY printer that understands it.
I did get it working in UWP using the code bellow, but it doesn't go trhough to the app store, it says I can't use these APIs.
public class RawPrintingService
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed.
di.pDocName = "RAW Document";
// Win7
di.pDataType = "RAW";
// Win8+
// di.pDataType = "XPS_PASS";
// Open the printer.
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
// Start a document.
if (StartDocPrinter(hPrinter, 1, di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
fs.Close();
fs.Dispose();
fs = null;
return bSuccess;
}
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
// How many characters are in the string?
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
I had to create a WPF app just to receive a URI with a path to a text file and them print it.
@ptorr-msft any update from the pos team?
Sorry, I've been out of the office. I got this link:
Can pos team provided any sample for MUNBYN Android Bluetooth Mobile Thermal Receipt Printer, MUNBYN 2 Inches 58MM Impresora térmica Printer with Leather Belt for Business ESC/POS, Does NOT Support iOS Devices,Square https://www.amazon.com/dp/B0753B5KYG/ref=cm_sw_r_cp_api_fabt1_IN-TFbH0SH19A
Sorry, I've been out of the office. I got this link:
Thanks for the link, but, we've all stumbled upon this link and it does nothing for what we are trying to achieve.
We just wanna be able to silently print stuff, if for that we need to request permission for the user, so be it.
It would be awesome to also be able to send esc/pos commands directly to the printer, just like in the code I posted above. It works on debug mode but it doesn't pass to the Microsoft Store because it says I'm using APIs that are not always available.
@ptorr-msft I also have same situation as Rothanan
@ptorr-msft can someone from the POS team can post on this issue?
Since this is now about POS printing, and not general consumer printing without prompts, can you start a new issue?
In my case, I was planning to use general consumer printers from UWP without the user prompts for each printing job, using something like a PrintAsync instead of ShowPrintUIAsync . It would be OK if this may require the creation of a new permission/capability for UWP AppModel like: AllowPrintingWithoutUserIteraction
I'm with @TonyHenrique, I need that too.
Hi everyone,
We develop POS software and we heavily rely on the printing options in WPF.
For example we create our layouts in XAML for receipt tickets / invoices / labels etc, even almost everything if I think about it.
We primarily use the PrintVisual method that we can use in WPF to print our XAML layouts to all kinds of printers.
Due to the nature of our clients (restaurants etc) they need to be able to quickly print a receipt without being bothered with dialogs before they can actually print something.
Is this something that wil be implemented in / ported to WinUI 3 Desktop?
We need this too.
I wonder how macOS deal with such issue. Is there a "print permission", or apps are allowed to print without confirm?
I don't believe macOS APIs for printing require permission. Actually Apple's printing API has a boolean that indicates whether to show or hide the dialog. So just setting the boolean to false will print without showing the dialog.
i am new in flutter develop and i want to make direct print for pdf file without showing the preview of printing for the user and make this for printer device that in the same network and i have its ip address .
Proposal: Allow the App to Print without showing the Confirmation Dialog to user
Summary
We should be able to programatically list printers, select the printer, configure paper size, orientation, settings... and PRINT without user interaction.
Rationale
I was trying to make a Touch Screen Kiosk Receipt Print application on UWP, but the samples show
await Windows.Graphics.Printing.PrintManager.ShowPrintUIAsync();
This brings the UWP Print Dialog.I need to print directly without this dialog. How to do this?
I need something like
await Windows.Graphics.Printing.PrintManager.PrintAsync();
We should be able to programatically list printers, select the printer, configure paper size, orientation, settings...This will enable:
Scope
Important Notes
This may require the creation of a new permission/capability for UWP AppModel: AllowPrintingWithoutUserIteraction
Open Questions