Is it possible to print a PDF document from a Windows Service? - c#

I want to build a Windows Service in C# which listens to an MSMQ queue for incoming print command messages. A message references a PDF document und contains the name of the destination printer (and maybe some other metadata like numbers of copies to print). The service should pick up the PDF and print it on the destination printer.
Question: Is it possible to print an arbitrary PDF on a printer from a Windows Service?
supplement:
The implementation should not depend on Acrobat Reader or any other "GUI tool". The Windows service runs headless. Besides I want to avoid to start a separate process for each print job when this is possible.

I use Spire.PDF library. The free version has a limit of 10 pages per file. No UI or Acrobat dependence
https://www.nuget.org/packages/Spire.PDF/
PdfDocument pdfdocument = new PdfDocument();
pdfdocument.LoadFromFile(path);
pdfdocument.PrinterName = printername;
pdfdocument.PrintDocument.PrinterSettings.Copies = copiesNumber;
pdfdocument.PrintDocument.Print();
pdfdocument.Dispose();

Related

.net Maui android how to retrieve file from external fileserver

I am making an app that allows you to open and edit a pdf file on tablets. Because i usually work with .NET, i decided to write it in .NET MAUI. That way i also have access to windows tablets.
It uses Itext as its main library to read and edit the pdf's.
I have an external shared fileserver that anyone can access when they are coneected to the WIFI.
I'd like to access that fileserver when i connect from my android tablet using Itext pdfreader.
How do I achieve this correctly?
Am i missing a library or a package which would allow to me to access that file?
Are there options i haven't discovered yet?
This works on windows tablets:
string dest "\\\\Path\\to\\File\\";
string file = "\\\\Path\\to\\File\\file.pdf";
PdfDocument pdfDoc = new PdfDocument(new PdfReader(file), new PdfWriter(dest));
I have tried :
string file = Environment.GetFolderPath(Environment.SpecialFolder.Windows)+ "\\Path\to\File\file.pdf";
string file = "\\\\Path\\to\\File\\file.pdf";
All of them result in file not found
Among the getfolderpath options ive tried a dozen, none of them seem to work.
thank you for your time
So i ended up solving this by transforming the document into a base64 string and sending it through an api that i had.
i used the classic httprequest aproach that you can look up and copy anywhere.

Not generating a PDF documents using CutePDF writer in windows service application C#

I converted text files to PDF documents using CutePDF Writer printer in windows forms application.It's working as expected but same block of code I used in c# windows service application to convert text files to PDF files.I'm not getting any exceptions while executing the code and not generating any PDF documents.
I created the following registry key settings for CutePDF writer
Setting the display mode:
HKEY_CURRENT_USER\Software\CutePDF Writer\BypassSaveAs
(0 = show Save as dialog box after spooling, 1 = do not show Save as dialog box.)
(This value is of type REG_SZ, not REG_DWORD)
Setting the filename:
HKEY_CURRENT_USER\Software\CutePDF Writer\OutputFile
(Use the key above to set the output file for the PDF. A full pathname
(e.g. d:\your folder\your file.pdf) is required.)
Not familiar with CutePDF Writer - but: as which user is the service running?
To clarify this: if the service runs as LocalService, the registry key HKEY_CURRENT_USER is not the same as the one from loged in user.
If that is the case, try HKEY_USERS\S-1-5-19 instead of HKEY_CURRENT_USER.

.NET printing on server side from asp.net

I have a Windows server running an ASP.NET application and a local printer connected to this machine. I need to print some documents from the server-side code.
So far I know, there's no managed API in .NET that is supported on server-side (service).
System.Printing namespace - is part of the WPF and is not supported to run on server-side as it may produce run-time exceptions (checked on msdn)
System.Drawing.Printing - is part of the WinForms and also not supported to run on server-side (checked on msdn)
The same problem was elaborated with help of Microsoft back in 2009 and the solution was to use an unmanaged XPS Print API as the only supported way back in that time. Problem described and solution with example posted is here: How to Print a Document on a Server via the XpsPrint API
However nowadays this is a problem as the XPS Print API is marked as not supported and may be unavailable in the future (msdn).
So, what is the supported way of printing from the server-side code?
It looks like there are more Win32 APIs that could be probably used, but there's no info on the web and it would probably be a nightmare...
Commercial solutions are accepted. Thank you.
So the best way would be to set up your printer on a print server and then install the print drivers on your web server with a reference to the printer you want to print to.
Then in code you can use System.Drawing.Printing to send the print job to whatever printer you just installed.
PrintDocument p1 = new PrintDocument();
p1.PrinterSettings.PrinterName = "\\PrintServer\NewPrinter";
p.PrintPage += new PrintPageEventHandler(this.Page_Print);
p1.Print();
protected void Page_Print(object sender, PrintPageEventArgs ev)
{
Brush b = new SolidBrush(Color.Black);
Font printFont = new Font("Lucida Sans Typewriter", 10);
ev.Graphics.DrawString("Hello World", printFont, b, x, y, StringFormat.GenericDefault);
}
Where this code will work technechally I would not recommend doing it this way since Microsoft itself says that this isn't supported.
I personally would push all print jobs to the client side. Install the printer locally like you did and then redirect the user to a page that they can print easily.
You can then write JavaScript if desired to call the browser specific print for them (if you want to automate that as well)
Or save a PDF server side and push the file as a download to the user making them download/save and then print the document via Adobe Reader or alternative app.

Open IManDocument in browser

I am using the WorkSite COM API to open an IMANEXT2Lib.IManFileOpenDlg which is working perfectly. Clicking on the document, I can retrieve the metadata, such as the document name, version, number etc.
Is there a method or technique available to read the document from WorkSite and prompt a download/open through a browser?
The IManage.IManDocument has the method GetCopy() available which will download a local copy to a specified directory, but this isn't really what I'm after.
If the clients have Worksite 8.5 or greater, you can use the IWL protocol in a hyperlink to force the client to use the IWL handler to download and launch the file themselves instead of streaming it from the browser. This has the added benefit of respecting the document's permissions and checking the document out to the user so they can make amends to the file if required.
An IWL formatted anchor tag in a web browser would look like the following:
Document x
Note that this will only work if the clients have Worksite 8.5 or newer installed.

Print to Network (Shared) Printer - Word Interop

I need to print a word document on server side to a network printer. My web page sends the document and file location to the server to open and replace mail merge items and then print the document to a preferred (not default) network printer. Preferred printer name changes when document selected on web page changes
I'm using Word 14.0 object library, Asp.Net MVC 4.0, .Net Framework 4.0, IIS 7 on windows server 2008 R2. On IIS I created an app pool that runs on an specific account Identity (accountName#DomainName). Load user profile set to true to load the network printer connections in to the registry. I allowed the Account to have permissions to run the word COM interop services. I was successful to open the document and replace the mail merge fields and save it as pdf to send the file as attachment to an email.
The word application has the default printer in its ActivePrinter property, so that I could print to default printer as well. But my final goal is to print the word to a preferred network printer before I close the word application and active document.
The following two Methods were causing exceptions if I try to change the ActivePrinter property.
Word.Application wordApp = new Word.Application();
First Method:
wordApp.ActivePrinter = "preferredPrinterName";
Second Method;
object[] oWordDialogParams = { "\\<serverName>\<PrinterName>", true };
string[] argNames = { "Printer", "DoNotSetAsSysDefault" };
object wordBasic = wordApp.WordBasic;
wordBasic.GetType().InvokeMember("FilePrintSetup"
, System.Reflection.BindingFlags.InvokeMethod
, null
, wordBasic
, oWordDialogParams
, null
, null
, argNames);
I found that the Word application object is not loading all the printers installed to the user account. It only loads the default printer. I'm assuming that it was the reason for exceptions when above two methods were attempting to change or add preferred printer to the application object because the printer I'm trying to set was never found in the active printers list.
How do I get all installed shared printers under user profile loaded in to the Word application object?
Using Office interop in a server-scenario (like ASP.NET, Windows Service etc.) is NOT supported by MS - see http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2
Additionally there have been several security-related changed since Windows Vista which basically make it really hard to do anything "desktop-like" in a Windows Service (IIS/ASP.NET is just a special case of Windows Service in this regard).
Another point is "printing" from a server-scenario is likely to cause problems since IIS is a (special) Windows Service... Windows Service usually don't have a "full/real" desktop which in turn is needed for printing robustly...
I don't think that there an easy solution for your scenario...
I would break it down to different components:
Word document handling (for example with Aspose.Words)
Create a PDF from the resulting Word file (for example with Aspose.Words)
Implement a HotFolder on the target network printer
Copy the PDF over to that HotFolder for printing
This would be a robust and supported option for your scenario...

Categories