It should work just fine from a console app. But yeah, Windows service or ASP.NET aren't so easy.
There are some suggestions here, but not easy ones (like using P/Invoke to use the C++ libraries to print, which was my first idea). You might be able to find people who have already done that if you search.
This answer recommends a third-party product: DevExpress' XtraReports.
There is also this guy on Reddit that described how he solved this exact thing. You could send him a message on Reddit and see if you can get his code somehow.
This example uses Microsoft.Office.Interop.Word
to print Word documents from a Windows service. Seems "hacky", but I don't see why it wouldn't work:
public class WordPrintTask
{
private static object locker = new Object();
public WordPrintTask() { }
public void PrintWord()
{
try
{
// Kill opened word instances.
if (KillProcess("WINWORD"))
{
// Thread safe.
lock (locker)
{
string fileName = "D:\\PrinterDocs\\TEST.docx";
string printerName = "\\\\10.0.0.89\\PRINTER1020";
if (File.Exists(fileName))
{
Application _application = new Application();
_application.Application.ActivePrinter = printerName;
object oSourceFilePath = (object)fileName;
object docType = WdDocumentType.wdTypeDocument;
object oFalse = (object)false;
object oMissing = System.Reflection.Missing.Value;
Document _document = _application.Documents.Open(ref oSourceFilePath,
ref docType,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing);
// Print
_application.PrintOut(ref oFalse, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
object saveOptions = WdSaveOptions.wdDoNotSaveChanges;
_document.Close(ref oFalse, ref oMissing, ref oMissing);
if (_application != null)
{
object oSave = false;
Object oMiss = System.Reflection.Missing.Value;
_application.Quit(ref oSave, ref oMiss, ref oMissing);
_application = null;
}
// Delete the file once it is printed
File.Delete(fileName);
}
}
}
}
catch (Exception ex)
{
KillProcess("WINWORD");
}
finally
{
}
}
private static bool KillProcess(string name)
{
foreach (Process clsProcess in Process.GetProcesses().Where(p => p.ProcessName.Contains(name)))
{
if (Process.GetCurrentProcess().Id == clsProcess.Id)
continue;
if (clsProcess.ProcessName.Contains(name))
{
clsProcess.Kill();
return true;
}
}
return true;
}
}