Resolved Error Creating Window Handle

Anonymous

Well-known member
Joined
Sep 29, 2020
Messages
84
Programming Experience
Beginner
I am creating a winform app that accepts a name and position as input and upon clicking the submit button generates a barcode of that name and prints that on the entered position in a pdf file(generates this as well). The app is giving me error on Environment.Exit(1) - Error Creating Window Handle in the code below -

C#:
if(string.IsNullOrEmpty(textboxName.Text))
{
    MessageBox.Show("Name cannot be empty");
    Environment.Exit(1);
}

I googled about this error and it showed that this error is related to a memory leak. I checked in the task manager. When I ran this app, the memory usage field show 7.5 kb.
This is what I am doing in my app -

There are only two textbox (name and position) and a submit button.


C#:
try{
if(string.IsNullOrEmpty(textboxName.Text))
{
    MessageBox.Show("Name cannot be empty");
    Environment.Exit(1);
}

if(string.IsNullOrEmpty(textboxPosition.Text))
{
    MessageBox.Show("Name cannot be empty");
    Environment.Exit(1);
}
string name = textboxName.Text;
string position = Convert.ToInt32(textboxPosition.Text);

BarcodeWriter writer = new BarcodeWriter()
{
    Format = BarcodeFormat.CODE_128,
    Options = new EncodingOptions
    {
        Height = 100,
        Width = 180,
        PureBarcode = false,
        Margin = 10,
    },
};

string content = @"*" + name + "*";
var bitmap = writer.Write(content);

using (MemoryStream ms = new MemoryStream())
            {
                bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                GeneratePDF(ms, position);
            }
}
catch
{
}

This is the generate PDF code
C#:
PdfDocument document = new PdfDocument();

try{
            // Create an empty page
            PdfPage page = document.AddPage();

            // Get an XGraphics object for drawing
            XGraphics gfx = XGraphics.FromPdfPage(page);

            XImage pic = XImage.FromStream(ms);
             
             string coordinates = GetCoordinates(position);

             string coordinate = coordinates.Split(',');

             int x = Convert.ToInt32(coordinate[0]);
             int y = Convert.ToInt32(coordinate[1]);

            gfx.DrawImage(pic,x , y , 110, 23);

            string filename = "Output.pdf";

            document.Save(@"E:\" + filename);

            MessageBox.Show("PDF saved successfully!");

}
catch
{
}

My PDF has 80 different static locations. These will never change. So, My GetCoordinates function has 80 different switch cases.

C#:
GetCoordinates(position)
{
    swtich(position)
    {
        case 1: x = 30;
               y = 40;
        break.
            case 2: x=60;
        y= 80;
        break;
        .
        .
        .
        .till case 80
    }
    return x +"," +y
}


For the time being, I have replaced the exit condition with the return statement and the app works now -

C#:
if(string.IsNullOrEmpty(textboxName.Text))

{

    MessageBox.Show("Name cannot be empty");

    return;

}

But I am not able to understand where my app is creating more than 10,000 handlers ( I have read that only 10,000 handlers per app is allowed).
 
First of all, Environment.Exit() should only be used as a last resort if you absolutely must abort a program. It terminates the application immediately. Invalid inputs that you can handle IS NOT something that should result in immediately exiting the program.

Furthermore, it looks like you are writing a GUI, you shouldn't be calling Exit() unless there is a fatal error that you must absolutely just stop everything and not clean up properly. In fact, for any C# program, you shouldn't be calling Exit() even if it is a console program. Calling Exit() is equivalent to the old C style of console program which would call exit(). You are writing in C# now, not C.

There also some other caveats about its use that you can read about in the documentation I linked to below. You might be hitting some of those corner cases.

 
The app is giving me error on Environment.Exit(1) - Error Creating Window Handle in the code below

Where exactly is that code that you have above? If it is near a point where WinForms is handling form creation/initialization, then the exception is not actually about the Exit() call, but rather about the form's window not being created. Basically Windows doesn't like it when someone tries to abort a window creation, and Windows throws an error, but the WinForms framework ends up noticing the error and maps it to a exception.
 
Not related to your problem, but I'll comment about it here. You are doing returning multiple values from your GetCoordinates() the wrong way. It looks like you have something like:
C#:
string GetCoordinates(int position)
{
    int x, y;
   :
    return x + "," + y;
}
and then on return you are parsing the returned string:
C#:
string coordinates = GetCoordinates(position);

string coordinate = coordinates.Split(',');

int x = Convert.ToInt32(coordinate[0]);
int y = Convert.ToInt32(coordinate[1]);

gfx.DrawImage(pic,x , y , 110, 23);

You don't want to be stringly-typed. That's for JavaScript programmers. We are C# programmers and believe in strongly-typed programming.

If you using an old version of C# without support for Tuples, the correct way would be to do something like:
C#:
struct Coordinates
{
    public int X;
    public int Y;

    public Coordinates(int x, int y)
    {
        X = x;
        Y = y;
    }
}

:

Coordinates GetCoordinates(int position)
{
    int x, y;
   :
    return new Coordinates(x, y);
}

:

Coordinates coordinates = GetCoordinates(position);
gfx.DrawImage(pic, coordinates.X, coordinates.Y, 110, 23);

If you are using a newer version of C# with Tuple support:
C#:
(int x, int y) GetCoordinates(int position)
{
    int x, y;
   :
    return (x, y);
}

:

var (x, y) = GetCoordinates(position);
gfx.DrawImage(pic, x, y, 110, 23);
 
My PDF has 80 different static locations. These will never change. So, My GetCoordinates function has 80 different switch cases.

If the positions are well known intervals of position on a diagonal you could simply have:
C#:
(int x, int y) GetCoordinates(int position)
{
    return (position * 30, position * 40);
}

If on the other hand your coordinates are more of a grid pattern, something like this would work:
C#:
(int x, int y) GetCoordinates(int position)
{
    int column = (position - 1) % NumberOfColumns + 1;
    int row = (position - 1) / NumberOfColumns + 1;
    return (column * 30, row * 40);
}

And if the coordinates can't really be defined by set formula, then you could just use a dictionary of positions and coordinates:
C#:
Dictionary<int, (int x, int y)> MapOfCoordinates = new()
{
    [1] = (30, 40),
    [2] = (33, 94),
    [3] = (75, 63),
    :
   [80] = (128, 6332)
}

:

var (x, y) = MapOfCoordinates[position];
 
In fact, for any C# program, you shouldn't be calling Exit() even if it is a console program.

So, how should I exit an application with a specific error code?
For example, I have to a console application that I run using task scheduler, and I want the app to return a specific error code to task scheduler, I normally write
C#:
 Environment.Exit(1)
or
C#:
 If(this condition is true)
Environment.Exit(5); //to handle special case
else
Environment.Exit(0); //exit normally.

What are the alternatives of this?
 
Where exactly is that code that you have above?

The validation code is in the button click event. This is the first thing that I am checking.

C#:
 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if(string.IsNullOrEmpty(textBox1.Text))
            {
                MessageBox.Show("Error");
                Environment.Exit(1);
            }
//rest of the code
 
Set Environment.ExitCode and close the app normally with Close method. If there are multiple forms open they can all be closed normally with Application.Exit method.
 
Back
Top Bottom