在没有打印对话框的情况下,从Windows服务中打印HTML文档

16

我正在使用Windows服务,并希望在服务启动时打印一个 .html 页面。我正在使用此代码,它可以成功地打印。但是会出现一个打印对话框,如何在不显示打印对话框的情况下进行打印?

public void printdoc(string document)
{
    Process printjob = new Process();

    printjob.StartInfo.FileName = document;
    printjob.StartInfo.UseShellExecute = true;
    printjob.StartInfo.Verb = "print";
    printjob.StartInfo.CreateNoWindow = true;
    printjob.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

    printjob.Start();
}

有没有其他方法可以打印而不显示打印对话框。


更新:回应这个

但是我已经使用了这个类,但当我调用

axW.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT,SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_PROMPTUSER , ref em, ref em);

当我从Windows服务中使用时,我的程序会被阻塞在这里,但是从Windows应用程序中使用时它能够正常工作。

5个回答

16

首先,这是代码:

using System.Reflection;
using System.Threading;
using SHDocVw;

namespace HTMLPrinting
{
  public class HTMLPrinter
  {
    private bool documentLoaded;
    private bool documentPrinted;

    private void ie_DocumentComplete(object pDisp, ref object URL)
    {
      documentLoaded = true;
    }

    private void ie_PrintTemplateTeardown(object pDisp)
    {
      documentPrinted = true;
    }

    public void Print(string htmlFilename)
    {
      documentLoaded = false;
      documentPrinted = false;

      InternetExplorer ie = new InternetExplorerClass();
      ie.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete);
      ie.PrintTemplateTeardown += new DWebBrowserEvents2_PrintTemplateTeardownEventHandler(ie_PrintTemplateTeardown);

      object missing = Missing.Value;

      ie.Navigate(htmlFilename, ref missing, ref missing, ref missing, ref missing);
      while (!documentLoaded && ie.QueryStatusWB(OLECMDID.OLECMDID_PRINT) != OLECMDF.OLECMDF_ENABLED)
        Thread.Sleep(100);

      ie.ExecWB(OLECMDID.OLECMDID_PRINT, OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref missing, ref missing);
      while (!documentPrinted)
        Thread.Sleep(100);

      ie.DocumentComplete -= ie_DocumentComplete;
      ie.PrintTemplateTeardown -= ie_PrintTemplateTeardown;
      ie.Quit();
    }
  }
}
  1. 通过在“添加引用”对话框的COM选项卡中添加对“Microsoft Internet Controls”的引用,可以访问SHDocVw名称空间。
  2. 有关InternetExplorer对象的更多信息,请参阅MSDN
  3. Navigate()方法将加载HTML文件。其他参数允许您指定可选参数,例如标志和标头。
  4. 在文档加载完成之前,我们无法打印。在此,我进入一个循环,等待调用DocumentComplete事件,此时设置一个标志,通知我们导航已完成。请注意,每当导航完成 - 成功或失败时,都会调用DocumentComplete。
  5. 一旦设置了documentLoaded标志,就会通过QueryStatusWB()查询打印状态,直到启用打印。
  6. 使用ExecWB()调用开始打印。指定OLECMDID_PRINT命令,以及选项OLECMDEXECOPT_DONTPROMPTUSER以便自动打印而不需用户交互。重要说明是,这将打印到默认打印机。要指定打印机,您将需要设置默认打印机(在代码中,您可以调用SetDefaultPrinter())。最后两个参数允许可选的输入和输出参数。
  7. 在打印完成之前,我们不希望退出。因此,再次进入循环。在触发PrintTemplateTeardown事件后,设置documentPrinted标志。然后可以清理对象。

1
有没有办法修改这个程序,使其打印成横向方向呢? - SeaDrive
1
在Windows 8.1上使用IE11时,出现了以下错误:调用的对象已与其客户端断开连接。(HRESULT异常代码:0x80010108 (RPC_E_DISCONNECTED)) - Dovlet Mamenov
@seaDrive,你是否已经得到了通过代码更改方向属性的答案?请与我们分享答案。 - SaddamBinSyed

1

这是另一种无需打印对话框的打印方法。您可以创建一个PrintDialog对象,初始化它,然后调用Print()方法。

下面的函数用于打印一个小的2"x0.75"条形码标签。您需要想出一种从HTML文件中获取Document对象的方法。

public void PrintToPrinter(string printerName)
{
    PrintDialog pd = new PrintDialog();
    pd.Document = userControl11.PrintDoc; // <--- Update this line with your doc
    pd.PrinterSettings.PrinterName = printerName;
    try
    {
            pd.Document.DocumentName = "My Label";
            pd.Document.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("2-.75", 200, 75);
            pd.Document.DefaultPageSettings.Margins = new System.Drawing.Printing.Margins(0, 0, 0, 0);
            //pd.PrinterSettings.Copies = (short)mNumCopies;
            pd.Document.PrinterSettings.Copies = (short) mNumCopies;
            pd.Document.Print();
    }
    catch
    {
        MessageBox.Show("INVALID PRINTER SPECIFIED");
    }
}

1
从这个网站http://www.ussbd.com/printhtm.html
using HtmlPrinter;
hpObj=new HtmlPrinter.HtmlPrinter();
hpObj.PrintUrlFromMemory(txtUrl.Text);

现在您可以将以下代码添加到您的项目中,以从源文本打印HTML页面:

HtmlPrinter.HtmlPrinter hpObj=new HtmlPrinter.HtmlPrinter();
hpObj.PrintHtml(txtString.Text, true);

如果你想不用打印对话框就进行打印,则使用以下代码:

hpObj.PrintHtml(txtString.Text, false); 

我不确定这是否有效。示例应用程序(也发布在Code Project上)在单击“直接打印URL”时弹出打印对话框,并且在“打印到文件”打印机(例如Microsoft XPS文档编写器)的情况下,弹出“另存为”对话框。在“从浏览器打印URL”的情况下,仅针对MXDW弹出“另存为对话框”。 - Jason Harrison

0
OLECMDEXECOPT_PROMPTUSER 似乎强制用户选择打印机和所有关联的内容,并且我相当确定这在服务中是不允许的。有人可以验证一下吗?

0

您可以使用 System.Drawing.Printing 命名空间中的 PrintDocument 类来更好地控制打印,有关更多信息,请参见 此处

例如,您可以执行以下操作:

using (PrintDocument doc = new PrintDocument())
{
    doc.PrintPage += this.Doc_PrintPage;
    doc.DefaultPageSettings.Landscape = true;
    doc.DocumentName = fileNameOfYourDocument;
    doc.Print();
}

然后为要打印的每个页面引发一个函数,并提供一个图形区域进行绘制

private void Doc_PrintPage(object sender, PrintPageEventArgs ev)
{
    ....
    ev.Graphics.DrawImage(image, x, y, newWidth, newHeight);
}

这确实需要您处理文本/图像在页面上的实际绘制,请参见此处获取更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接