我正在编写一个应用程序,它将(呈现的)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());
非常简单的代码。只是遇到了一些麻烦。
答案 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();
}