views:

1855

answers:

7

I want to print HTML from a C# web service. The Web Browser control is overkill, and does not function well in a service-environment, nor does it function well on a system with very tight security constraints. Is there any sort of free .NET library that will support the printing of a basic HTML page? Here is the code I have so far, that is not running properly.

public void PrintThing(string document)
{
    if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
    {
        Thread thread =
            new Thread((ThreadStart) delegate { PrintDocument(document); });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }
    else
    {
        PrintDocument(document);
    }
}

protected void PrintDocument(string document)
{
    WebBrowser browser = new WebBrowser();
    browser.DocumentText = document;
    while (browser.ReadyState != WebBrowserReadyState.Complete)
    {
        Application.DoEvents();
    }
    browser.Print();
}

This works fine when called from UI-type threads, but nothing happens when called from a service-type thread. Changing Print() to ShowPrintPreviewDialog() yields the following IE script error:

Error: 'dialogArguments.___IE_PrintType' is null or not an object URL: res://ieframe.dll/preview.dlg

And a small empty print preview dialog appears.

A: 

What version of .net are you using? I think if you using 3.5 there is a document render that is NOT the WebBrowser Control. but it uses WPF stuff.

w-ll
2.0, and we can't move to 3.5 for this.
Chris Marasti-Georg
A: 

I know that Visual Studio itself (at least in 2003 version) references the IE dll directly to render the "Design View".

It may be worth looking into that.

Otherwise, I can't think of anything beyond the Web Browser control.

EndangeredMassa
+8  A: 

You can print from the command line using the following:

rundll32.exe %WINDIR%\System32\mshtml.dll,PrintHTML "%1"

Where %1 is the file path of the html file to be printed.

If you don't need to print from memory (or can afford to write to the disk in a temp file) you can use:

using (Process printProcess = new Process())
{
string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
printProcess.StartInfo.FileName = systemPath + @"\rundll32.exe";
printProcess.StartInfo.Arguments = systemPath + @"\mshtml.dll,PrintHTML """ + fileToPrint + @"""";
printProcess.Start();
}

N.B. This only works on Windows 2000 and above I think.

ICR
Great answer - was going to mark it accepted, and ran my test. Seems that dll still pops up the Print dialog, and as this is to run as an unattended Windows Service, we need to bypass that somehow. I've pretty much exhausted Google, and I'm at my wits end.
Chris Marasti-Georg
A: 

I don't know the specific tools, but there are some utilities that record / replay clicks. In other words, you could automate the "click" on the print dialog. (I know this is a hack, but when all else fails...)

Greg Ogle
A: 

Maybe this will help. http://www.codeproject.com/KB/printing/printhml.aspx Also not sure what thread you are trying to access the browser control from, but it needs to be STA

Note - The project referred to in the link does allow you to navigate to a page and perform a print without showing the print dialog.

NastyNateDoggy
A: 

Another way is export HTML to RTF format, which more convenient for printing. For example with help of SautinSoft's HTML-to-RTF library:

SautinSoft.HtmlToRtf h = new SautinSoft.HtmlToRtf();
//Set page size, orientation and page margins
h.PageStyle.PageSize.Letter();
h.PageStyle.PageOrientation.Landscape();
h.PageStyle.PageMarginLeft.mm(30f);
string rtf = h.ConvertString(html);

Next use RichTextBox to print produced RTF in C#.

Maximus
Can you print from a RichTextBox when running as a service?
Chris Marasti-Georg
A: 

If you've got it in the budget (~$3000), check out PrinceXML.

It will render HTML into a PDF, functions well in a service environment, and supports advanced features such as not breaking a page in the middle of a table cell (which a lot of browsers don't currently support).