I'm new programmer and trying to make a program with c# which clicks on specific coordinates on the screen and search image from screen, and when find it to click on it. Program is working fine but after 30-40min get crash. When it crash window pop up - Unhandled exception has occurred in your application....
Parameter is not valid
Here are details:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
at Uncle_s_Bot.Form1.Screenshot()
at Uncle_s_Bot.Form1.btnStart_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Here and the code of the program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace Uncle_s_Bot
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData,
int dwExtraInfo);
public enum MouseEventFlags : uint
{
MOUSEEVENTF_ABSOLUTE = 0x8000,
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_MIDDLEDOWN = 0x0020,
MOUSEEVENTF_MIDDLEUP = 0x0040,
MOUSEEVENTF_MOVE = 0x0001,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_XDOWN = 0x0080,
MOUSEEVENTF_XUP = 0x0100,
MOUSEEVENTF_WHEEL = 0x0800,
MOUSEEVENTF_HWHEEL = 0x01000
}
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
Bitmap bmpScreenshot;
Point location;
bool success;
bool MaybeAvailable = false;
while (true)
{
// Point 1
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(95, 140);
mouseClick();
Thread.Sleep(7500);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 2
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(135, 135);
mouseClick();
Thread.Sleep(10000);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 3
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(180, 140);
mouseClick();
Thread.Sleep(10000);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 4
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(190, 170);
mouseClick();
Thread.Sleep(8500);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 5
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(150, 185);
mouseClick();
Thread.Sleep(10000);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 6
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(180, 210);
mouseClick();
Thread.Sleep(10000);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 7
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(150, 240);
mouseClick();
Thread.Sleep(8500);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 8
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(95, 235);
mouseClick();
Thread.Sleep(9500);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 9
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(110, 200);
mouseClick();
Thread.Sleep(10000);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 10
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(80, 170);
mouseClick();
Thread.Sleep(10000);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
// Point 11
do
{
bmpScreenshot = Screenshot();
success = FindBitmap(Properties.Resources.bmp_Bonus, bmpScreenshot, out location);
if (success == true)
{
Cursor.Position = location;
mouseClick();
Thread.Sleep(1500);
MaybeAvailable = true;
}
else
{
Cursor.Position = new Point(120, 165);
mouseClick();
Thread.Sleep(11500);
MaybeAvailable = false;
}
}
while (MaybeAvailable);
}
}
private void mouseClick()
{
mouse_event((uint)MouseEventFlags.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
Thread.Sleep((new Random()).Next(20, 30));
mouse_event((uint)MouseEventFlags.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
private Bitmap Screenshot()
{
// save snapshot of screen
Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
// create a graphic object so we can draw the screen in the bitmap
Graphics g = Graphics.FromImage(bmpScreenshot);
// copy from screen into the bitmap we created
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
// return the screenshot
return bmpScreenshot;
}
// Find location of a bitmap within another bitmap and return if it was succesufulyy found
private bool FindBitmap(Bitmap bmpNeedle, Bitmap bmpHaystack, out Point location)
{
for (int outerX = 0; outerX < bmpHaystack.Width - bmpNeedle.Width; outerX++)
{
for (int outerY = 0; outerY < bmpHaystack.Height - bmpNeedle.Height; outerY++)
{
for (int innerX = 0; innerX < bmpNeedle.Width; innerX++)
{
for (int innerY = 0; innerY < bmpNeedle.Height; innerY++)
{
Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);
if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
{
goto notFound;
}
}
}
location = new Point(outerX, outerY);
return true;
notFound:
continue;
}
}
location = Point.Empty;
return false;
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Creating new bitmaps, graphics is leading to internal GDI+ function calls. All these functions can end up with error and the errors are translated to .NET exceptions (unfortunately without additional parameter names, infos etc.). Some of the errors could be really difficult to understand because of this.
Some issues could happen because of handle leak and memory leak (in case of GDI+). For instance, creating a lot of really large bitmaps allocate a lot of contiguous blocks in an unmanaged space. GC does not know about the memory pressure and does not try to clean. Passing Width and Height large enough after let's say 100 calls might notice lack of memory and complain about too large width and height throwing the ArgumentException.
First of all, please consider disposing bitmaps if you do not need them. Do not forget to dispose graphics as well.
If it does not helps, please let me know.