如何在打印时关闭Web浏览器?

时间:2010-11-12 16:15:01

标签: c# winforms

我正在编写一个应用程序,它将(呈现的)HTML页面打印到运行该应用程序的计算机上安装的每台打印机上。我这样做是通过创建一个WebBrowser,在其上调用print(),然后关闭表单。我为该计算机上安装的每台打印机执行此操作。

我的问题是,当我打电话试图关闭表单时,页面不会被打印。关于如何使打印成为独立后台进程的任何想法,以便我可以在打印时关闭表单?

这是我目前在表单中的代码:

    public PrintForm()
    {
        InitializeComponent();

        string doc = "C:\\Path\\To\\file.htm";
        browser.Url = new Uri(doc);
    }

    private void PrintForm_Shown(object sender, EventArgs e)
    {
        Thread t = new Thread(browser.Print);
        t.IsBackground = false;
        t.Start();

        this.Close();
    }

我有另一个类将每个已安装的打印机切换为默认打印机(以编程方式绕过打印对话框的唯一方法),然后调用

Applicated.Run(new PrintForm());

非常简单的代码。只是遇到了一些麻烦。

2 个答案:

答案 0 :(得分:2)

是的,这不行。您将面临的第一个障碍是WebBrowser是一个公寓线程COM组件。在一个线程上调用它的Print方法实际上不起作用,COM遵循组件的线程要求,并调用它在UI线程上创建的线程的调用。

您的代码遭到炸弹,因为表单的Close()调用也会释放其所有子控件。包括WebBrowser。您可以将其从Control集合中删除以防止这种情况发生,但是在完成打印时仍然必须调用其Dispose()方法。

解决这个问题在技术上是不可能的,你必须创建一个泵送消息循环的STA线程。检查我的代码this thread中的方法。

答案 1 :(得分:0)

您需要将Background = true更改为IsBackground = false

当IsBackGround为true时,线程无法阻止进程结束。当所有前台线程结束时,无论任何后台线程的状态如何,该过程都将结束。通过将IsBackground设置为false,可以在主/用户界面线程退出后使打印线程能够支持进程。

UI线程将结束,但进程(可在控制面板中访问)将保持运行,直到打印线程(以及IsBackground = false的所有其他线程)完成。在所有前台线程(包括打印)都存在之前,该过程不会结束。

点击编辑:

在打印线程内创建WebBrowser的示例。如果您不需要任何用户输入,甚至可能不需要创建和关闭Windows窗体。

Thread t = new Thread (new ParameterizedThreadStart(PrintUrl));
t.IsBackground = false;
t.Start((object)@"http://www.stackoverflow.com");

static void PrintUrl(object url)
{
    WebBrowser browser = new WebBrowser();
    browser.Url = new Uri((string)url);
    browser.Print();
}