0

I have a program that is supposed to print a string provided as argument to the default printer in the system. The string is HTML-formatted.

As an attempt to develop a solution, I came up with the following code:

Program.cs

using System;
using System.Windows.Forms;
using System.Threading;

namespace Print2
{
    class Program
    {
        private const bool DEBUG = false;

        [STAThread]
        static void Main(string[] args)
        {
            string html = args[0];
            RunBrowserThread(html);
        }

        // Mostly based on code by Hans Passant <https://stackoverflow.com/users/17034/hans-passant>
        // See: https://stackoverflow.com/a/4271581/3258851
        // (CC BY-SA 2.5)
        private static void RunBrowserThread(string html)
        {
            var t = new Thread(() => {
                var wb = new WebBrowser();
                wb.DocumentCompleted += Browser_DocumentCompleted;
                wb.DocumentText = html;
                Application.Run();
            });
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }

        static void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            var wb = sender as WebBrowser;
            wb.Print();
            
            if (DEBUG)
                MessageBox.Show("Printed " + wb.DocumentText);
            
            Application.ExitThread();
        }
    }
}

This is a Console Application (.NET Core 3.1), and I manually edited the .csproj file according to this in order to have support for System.Windows.Forms.WebBrowser:

Print2.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <Version>1.0.0-beta10</Version>
    <AssemblyVersion>1.0.0.10</AssemblyVersion>
    <FileVersion>1.0.0.10</FileVersion>
  </PropertyGroup>

</Project>

The problem I'm facing is: when the DEBUG constant is set to false (and, as a consequence, no messagebox is shown), the wb.Print() call doesn't seem to work as the document is not placed to the printer's pool. The exit code does not indicate an error.

How do I get the program to work without having to display a messagebox?

What I have tried, to no effect:

  • defining <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> in the .csproj according to the linked answer
  • calling Thread.Sleep() or t.Join() right after the call to t.Start().

This is not a matter of the application exiting too soon, as I can Thread.Sleep all I want (and confirm under the Windows Task Manager) and still the behavior is the same.

Marc.2377
  • 7,807
  • 7
  • 51
  • 95
  • Can you show something more realistic as [MCVE]? Something that does not instantly quit before doing anything (as that clearly can't be representing your actual code)? – Alexei Levenkov Dec 04 '20 at 00:43
  • @AlexeiLevenkov, that is my actual, full code. It appears that my problem is precisely one of the application returning without doing anything... – Marc.2377 Dec 04 '20 at 00:46
  • (The program is supposed to print the string to the system printer and then quit right after, without opening a console or form window). – Marc.2377 Dec 04 '20 at 00:47
  • Maybe you should wait till at least it start doing anything, or even better finish before exiting? (Actually I don't believe that adding MessageBox.Show helps at all - it should not really matter at all as code should quite before getting to that point...) – Alexei Levenkov Dec 04 '20 at 00:49
  • @AlexeiLevenkov, it works consistently if I call `MessageBox.Show()` (by defining `DEBUG = true`). In fact the program keeps running until I close the message box. – Marc.2377 Dec 04 '20 at 00:51
  • 1
    All that the message box does is stopping the program from terminating too soon. Google "c# webbrowser print done event" for hits, takes you [here](https://stackoverflow.com/questions/22633471/webbrowser-wait-until-finished-printing) for example. – Hans Passant Dec 04 '20 at 01:00
  • @HansPassant Indeed that seems to be the case; however, why then adding `Thread.Sleep` with a long time like 10000 ms, or even adding `t.Join()`, did not solve the problem? – Marc.2377 Dec 04 '20 at 01:04

0 Answers0