Printing from windows service on windows 8 fails
I have a windows service application written in C# .NET. This application is used to generate a report pdf by printing document to local software printer that generates PDFs. This works well on Windows XP and Windows 7. Unfortunately I found that on Windows 8 it fails. Then I found out that printing to any (even physical) printer on Windows 8 fails when I print from my service. What is missing in my program to work? I’m printing this way:
Service is set to ‘system account’ without ‘interacting with desktop’ (but I tried that too or to login as local user).
This results into exception on Windows 8. When using ‘Print ticket — Approach 1’:
Using ‘Print ticket — Approach 2’:
I would say that service is able to find those printers because when I have tried to print to non-existing printer and I got «invalid printer name» exception.
In case someone is interested in trying — here is my sample service application that tries to print simple document to printer selected in config file: http://bin.mypage.sk/FILES/PrintTestService.rar
Interesting. When I tried a different printing code there is no error:
Unfortunately this is a older GDI+ code using the System.Drawing.Graphics library which is not compatible with my code that produces paginated document in form of System.Windows.Media.Visual objects. So I can’t use it to print my document unless I’d like to spend two weeks of creating the pagination of my document from scratch.
There is discussion about this issue here: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/96e7fc10-3f08-4808-b748-692e30377293 There is a ‘workaround’ for it to use ‘anyCPU’ platform. This workaround really works (I tried it) but it is not usable in my case when my service needs to be x86. I have contacted MS support through our company to find a real solution.
3 Answers 3
At http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/fdcfa0fa-50aa-4a61-be79-5b4c8f65fbf7/ we see that this was reported to Microsoft and confirmed as a bug in Windows 8 and Windows Server 2012.
This bug is triggered when trying to print from a 32bit process in non-standard user session (like e.g. a service).
According to Microsoft, this a bug was resolved in Windows 8.1 and Windows Server 2012 R2. However, we could still reproduce it on Windows 8.1.
On the same site, a workaround is given by Microsoft. This workaround solved the problem for us on Windows 8.1. It probably also works on Windows 8 and Windows Server 2012.
The workaround goes as follows:
Open Regedit and go to HKEY_CLASSES_ROOT\CLSID
Check the value of the «AppID» Registry Entry. In our case this was
Since this is a bug in Windows, you cannot fix it in your code. The workaround might have side effects, but we haven’t seen any so far in our scenario.
Solution: To wait for Microsoft to fix this bug. I have reported the bug (REG:113040910349062), they have confirmed it, but fix won’t be soon (in next months) and there is no date specified for it.
Workaround that we use: Create a small application that handles the printing, compile it as ‘anyCPU’ application and run it from service application (which I can’t compile as ‘anyCPU’ — I need ‘x86’ because of its dependencies). This workaround was tested and works. But it is dirty + causes overhead + extra care.
Edit: Microsoft provides a hotfix that should fix this problem in Windows 8 : http://support.microsoft.com/kb/2872151/EN-US ( «You cannot print from a 32-bit WPF application in an x64-based version of Windows 8 or Windows Server 2012» )
Edit (2013-11-04): we have tested the hotfix and it does not work on Windows 8 or Windows 8.1. Currently we are again in a phase of communicating with Microsoft.
Edit (2014-beginning of the year): we have received a response from Microsoft that they don’t know how to fix this bug and the bug is closed. So only solution for us at the moment is having a small app exe compiled as AnyCPU which is called by our x86 service. This approach works, but causes slowdown and our product is also harder to maintain because of this.
Print html document from Windows Service without print dialog
I am using a windows service and i want to print a .html page when the service will start. I am using this code and it’s printing well. But a print dialog box come, how do i print without the print dialog box?
Have there any other way to print this without showing the print dialog box.
Update: in response to this:
But i have already used this class but when i am calling the
My program getting block here when i am using from window service but it is working fine from windows application.
5 Answers 5
First off, here’s the code:
- You can access the SHDocVw namespace by adding a reference to ‘Microsoft Internet Controls’, found on the COM tab of the Add Reference dialog.
- More information on the InternetExplorer object can be found on MSDN.
- The Navigate() method will load the HTML file. The other parameters allow you to specify optional parameters, such as flags and headers.
- We can’t print until the document is loaded. Here, I enter a loop waiting until the DocumentComplete event is called, upon which a flag is set notifying us that navigation has completed. Note that DocumentComplete is called whenever navigation is finished — upon success or failure.
- Once the documentLoaded flag is set, the printing status is queried via QueryStatusWB() until printing is enabled.
- Printing is started with the ExecWB() call. The OLECMDID_PRINT command is specified, along with the option OLECMDEXECOPT_DONTPROMPTUSER to automatically print without user interaction. An important note is that this will print to the default printer. To specify a printer, you will have to set the default printer (in code, you could call SetDefaultPrinter()). The two final parameters allow optional input and output parameters.
- We don’t want to quit until printing is complete, so once again a loop is entered. After the PrintTemplateTeardown event is fired, the documentPrinted flag is set. The objects can then be cleaned up.
Print from Windows Service, no dialog, no user interaction
I would like to print from a Windows Service in C# using Visual Studio 2010. So far, I have only been partially successful by using the code found here:
The current problem I am experiencing is two fold, which I have only discovered by allowing the service to interact with the desktop:
1) When the URL is entered in as the HTML location, it will request credentials for that location (a network shared IIS web server that I DO NOT have the ability to alter in any way, which requests a username and password to access the information).
2) After I enter credentials, the default printer is ALWAYS the XPS printer, no matter what I do to SetDefaultPrinter (two different ways I have found to do this). I have discovered this is because the printer I want to print to is also a network printer, which the Local System account cannot access (apparently). I have not found a way around this problem.
I would like to get around both of these problems by entering the credentials needed programmatically (this is a network share credential set) and then print to a network printer. In other desktop applications I have successfully printed to each of these network printers even though I do not have each one installed.
Attempting to log in using my credentials instead of the Local System account does not solve either problem. I am using Windows XP.
Assuming I get this to work, I will also need to install the service on another server, so if it is necessary to preinstall each printer I will need to know what steps to take to ensure the Local System account has access to them. The server I will install on will likely be a Windows Server 2003 or 2008, but will have the same network access as the development machine.
EDIT: I attempted a solution of having it Log on as other accounts, all of which should have credentials (and, in fact, if those credentials are entered when it is running as Local System with desktop interaction, those credentials are accepted). Each user that this has been attempted with has had the default printer set to the printer I am trying to test print to, but no print occurs. The only time I know for sure it is trying to use the XPS printer is when it is logged on as Local System with desktop interaction.