从Windows服务打印html文档,无需打印对话框

时间:2022-10-30 21:55:20

I am using a windows service and i want to print a .html page when the service will start. I am using this code and it's printing well. But a print dialog box come, how do i print without the print dialog box?

我正在使用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();
}

Have there any other way to print this without showing the print dialog box.

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


Update: in response to this:

更新:回应:

But i have already used this class but when i am calling the

但是我已经使用过这个课了,但是当我打电话的时候

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

My program getting block here when i am using from window service but it is working fine from windows application.

当我从窗口服务使用时,我的程序阻止在这里,但它从Windows应用程序正常工作。

5 个解决方案

#1


First off, here's the code:

首先,这是代码:

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. You can access the SHDocVw namespace by adding a reference to 'Microsoft Internet Controls', found on the COM tab of the Add Reference dialog.
  2. 您可以通过添加对“添​​加引用”对话框的“COM”选项卡上的“Microsoft Internet Controls”的引用来访问SHDocVw命名空间。

  3. More information on the InternetExplorer object can be found on MSDN.
  4. 有关InternetExplorer对象的更多信息可以在MSDN上找到。

  5. The Navigate() method will load the HTML file. The other parameters allow you to specify optional parameters, such as flags and headers.
  6. Navigate()方法将加载HTML文件。其他参数允许您指定可选参数,例如标志和标头。

  7. We can't print until the document is loaded. Here, I enter a loop waiting until the DocumentComplete event is called, upon which a flag is set notifying us that navigation has completed. Note that DocumentComplete is called whenever navigation is finished - upon success or failure.
  8. 在加载文档之前我们无法打印。在这里,我进入一个循环,等待调用DocumentComplete事件,然后设置一个标志,通知我们导航已完成。请注意,导航完成后会调用DocumentComplete - 成功或失败时。

  9. Once the documentLoaded flag is set, the printing status is queried via QueryStatusWB() until printing is enabled.
  10. 设置documentLoaded标志后,将通过QueryStatusWB()查询打印状态,直到启用打印。

  11. Printing is started with the ExecWB() call. The OLECMDID_PRINT command is specified, along with the option OLECMDEXECOPT_DONTPROMPTUSER to automatically print without user interaction. An important note is that this will print to the default printer. To specify a printer, you will have to set the default printer (in code, you could call SetDefaultPrinter()). The two final parameters allow optional input and output parameters.
  12. 使用ExecWB()调用启动打印。指定了OLECMDID_PRINT命令以及选项OLECMDEXECOPT_DONTPROMPTUSER以在没有用户交互的情况下自动打印。一个重要的注意事项是,它将打印到默认打印机。要指定打印机,您必须设置默认打印机(在代码中,您可以调用SetDefaultPrinter())。两个最终参数允许可选的输入和输出参数。

  13. We don't want to quit until printing is complete, so once again a loop is entered. After the PrintTemplateTeardown event is fired, the documentPrinted flag is set. The objects can then be cleaned up.
  14. 我们不希望在打印完成之前退出,因此再次输入循环。触发PrintTemplateTeardown事件后,将设置documentPrinted标志。然后可以清理对象。

#2


From this site http://www.ussbd.com/printhtm.html

来自这个网站http://www.ussbd.com/printhtm.html

using HtmlPrinter;
hpObj=new HtmlPrinter.HtmlPrinter();
hpObj.PrintUrlFromMemory(txtUrl.Text);

Now you add the code in your project to print html page from its source text:

现在,在项目中添加代码,从源文本中打印html页面:

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

If you want to print without the print dialog then use the following line:

如果要在没有打印对话框的情况下进行打印,请使用以下行:

hpObj.PrintHtml(txtString.Text, false); 

#3


Here's another way to print without a print dialog. You create a PrintDialog object, initialize it and then call the Print() method.

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

The function below is used to print a small 2"x0.75" barcode label. You'll need to figure out a way to get an Document object from the html file.

以下功能用于打印小的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");
    }
}

#4


You can use the PrintDocument class in the System.Drawing.Printing namespace to give you more control over the printing, see here for more info.

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

For example you can do the following:

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

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

Then a function is raised for each page to be printed and you are given a Graphics area to draw to

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

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

This does require you handle the actual drawing on the text/image to the page, see here for more info.

这确实需要您将文本/图像上的实际绘图处理到页面,有关详细信息,请参阅此处。

#5


OLECMDEXECOPT_PROMPTUSER seems to force a prompt to the user to select printer and all associated stuff, which I am pretty sure is not allowed from a service. Can someone verify this?

OLECMDEXECOPT_PROMPTUSER似乎强制提示用户选择打印机和所有相关的东西,我很确定不允许从服务。有人可以验证吗?

#1


First off, here's the code:

首先,这是代码:

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. You can access the SHDocVw namespace by adding a reference to 'Microsoft Internet Controls', found on the COM tab of the Add Reference dialog.
  2. 您可以通过添加对“添​​加引用”对话框的“COM”选项卡上的“Microsoft Internet Controls”的引用来访问SHDocVw命名空间。

  3. More information on the InternetExplorer object can be found on MSDN.
  4. 有关InternetExplorer对象的更多信息可以在MSDN上找到。

  5. The Navigate() method will load the HTML file. The other parameters allow you to specify optional parameters, such as flags and headers.
  6. Navigate()方法将加载HTML文件。其他参数允许您指定可选参数,例如标志和标头。

  7. We can't print until the document is loaded. Here, I enter a loop waiting until the DocumentComplete event is called, upon which a flag is set notifying us that navigation has completed. Note that DocumentComplete is called whenever navigation is finished - upon success or failure.
  8. 在加载文档之前我们无法打印。在这里,我进入一个循环,等待调用DocumentComplete事件,然后设置一个标志,通知我们导航已完成。请注意,导航完成后会调用DocumentComplete - 成功或失败时。

  9. Once the documentLoaded flag is set, the printing status is queried via QueryStatusWB() until printing is enabled.
  10. 设置documentLoaded标志后,将通过QueryStatusWB()查询打印状态,直到启用打印。

  11. Printing is started with the ExecWB() call. The OLECMDID_PRINT command is specified, along with the option OLECMDEXECOPT_DONTPROMPTUSER to automatically print without user interaction. An important note is that this will print to the default printer. To specify a printer, you will have to set the default printer (in code, you could call SetDefaultPrinter()). The two final parameters allow optional input and output parameters.
  12. 使用ExecWB()调用启动打印。指定了OLECMDID_PRINT命令以及选项OLECMDEXECOPT_DONTPROMPTUSER以在没有用户交互的情况下自动打印。一个重要的注意事项是,它将打印到默认打印机。要指定打印机,您必须设置默认打印机(在代码中,您可以调用SetDefaultPrinter())。两个最终参数允许可选的输入和输出参数。

  13. We don't want to quit until printing is complete, so once again a loop is entered. After the PrintTemplateTeardown event is fired, the documentPrinted flag is set. The objects can then be cleaned up.
  14. 我们不希望在打印完成之前退出,因此再次输入循环。触发PrintTemplateTeardown事件后,将设置documentPrinted标志。然后可以清理对象。

#2


From this site http://www.ussbd.com/printhtm.html

来自这个网站http://www.ussbd.com/printhtm.html

using HtmlPrinter;
hpObj=new HtmlPrinter.HtmlPrinter();
hpObj.PrintUrlFromMemory(txtUrl.Text);

Now you add the code in your project to print html page from its source text:

现在,在项目中添加代码,从源文本中打印html页面:

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

If you want to print without the print dialog then use the following line:

如果要在没有打印对话框的情况下进行打印,请使用以下行:

hpObj.PrintHtml(txtString.Text, false); 

#3


Here's another way to print without a print dialog. You create a PrintDialog object, initialize it and then call the Print() method.

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

The function below is used to print a small 2"x0.75" barcode label. You'll need to figure out a way to get an Document object from the html file.

以下功能用于打印小的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");
    }
}

#4


You can use the PrintDocument class in the System.Drawing.Printing namespace to give you more control over the printing, see here for more info.

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

For example you can do the following:

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

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

Then a function is raised for each page to be printed and you are given a Graphics area to draw to

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

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

This does require you handle the actual drawing on the text/image to the page, see here for more info.

这确实需要您将文本/图像上的实际绘图处理到页面,有关详细信息,请参阅此处。

#5


OLECMDEXECOPT_PROMPTUSER seems to force a prompt to the user to select printer and all associated stuff, which I am pretty sure is not allowed from a service. Can someone verify this?

OLECMDEXECOPT_PROMPTUSER似乎强制提示用户选择打印机和所有相关的东西,我很确定不允许从服务。有人可以验证吗?