I want to make a screen capturer that can capture many times whenever the user clicked it (I want to create my own, so don't just tell me that there's a software for that, and for my own practice too) :)
I tried searching all of the possible solutions from StackOverflow (Above link is one of the many that I've found), but I can't any that can help with my problem.
This is my Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Screen_Monitoring
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCaptureScreen_Click(object sender, EventArgs e)
{
String screenName = AppDomain.CurrentDomain.BaseDirectory + "ScreenImages/screen.jpg";
CaptureScreen(screenName);
screen1.Image = Image.FromFile(screenName);
}
private void CaptureScreen(String screenName)
{
Rectangle bounds = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
bitmap.Save(screenName, ImageFormat.Jpeg);
}
}
}
}
The problem occurs when I tried to save my Picture Box twice (It always happened the second time)
Error Message: System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI+.'
This is my Form
Don't mind ScreenCapture.cs, that's just one of the other solution I tried to try Screen Capturing.
EDIT-FOR-DUPLICATE I've tried Overwrite Existing Image just now, and it's still the same error as before.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Screen_Monitoring
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCaptureScreen_Click(object sender, EventArgs e)
{
String screenName = AppDomain.CurrentDomain.BaseDirectory + "ScreenImages/screen.jpg";
if (File.Exists(screenName)) File.Delete(screenName);
CaptureScreen(screenName);
screen1.Image = Image.FromFile(screenName);
}
private Image GetCopyImage(string path)
{
using (Image im = Image.FromFile(path))
{
Bitmap bm = new Bitmap(im);
return bm;
}
}
private void CaptureScreen(String screenName)
{
Rectangle bounds = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
bitmap.Save(screenName, ImageFormat.Jpeg);
bitmap.Dispose();
}
}
}
}
Now this is where I got the error (Again, after the second click)
if (File.Exists(screenName)) File.Delete(screenName);
Error Message: System.IO.IOException: 'The process cannot access the file 'C:\Users\Michael HT\Documents\2. Work\Project\Screen Monitoring\Screen Monitoring\bin\Debug\ScreenImages\screen.jpg' because it is being used by another process.'
EDIT-ADDING-NULL-BEFORE-DELETING
private void btnCaptureScreen_Click(object sender, EventArgs e)
{
String screenName = AppDomain.CurrentDomain.BaseDirectory + "ScreenImages/screen.jpg";
screen1.Image = null;
if (File.Exists(screenName)) File.Delete(screenName);
CaptureScreen(screenName);
screen1.Image = Image.FromFile(screenName);
}
I tried adding null before deleting, still got the same error at
if (File.Exists(screenName)) File.Delete(screenName);
Error Message: System.IO.IOException: 'The process cannot access the file 'C:\Users\Michael HT\Documents\2. Work\Project\Screen Monitoring\Screen Monitoring\bin\Debug\ScreenImages\screen.jpg' because it is being used by another process.'
EDIT-FOR-THE-SOLUTION
I tried this and it worked!!
private void btnCaptureScreen_Click(object sender, EventArgs e)
{
String screenName = AppDomain.CurrentDomain.BaseDirectory + "ScreenImages/screen.jpg";
if(screen1.Image != null) screen1.Image.Dispose();
screen1.Image = null;
CaptureScreen(screenName);
screen1.Image = Image.FromFile(screenName);
}
Here's the correct code :)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Screen_Monitoring
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCaptureScreen_Click(object sender, EventArgs e)
{
String screenName = AppDomain.CurrentDomain.BaseDirectory + "ScreenImages/screen.jpg";
if(screen1.Image != null) screen1.Image.Dispose();
screen1.Image = null;
CaptureScreen(screenName);
screen1.Image = Image.FromFile(screenName);
}
private Image GetCopyImage(string path)
{
using (Image im = Image.FromFile(path))
{
Bitmap bm = new Bitmap(im);
return bm;
}
}
private void CaptureScreen(String screenName)
{
Rectangle bounds = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
bitmap.Save(screenName, ImageFormat.Jpeg);
}
}
}
}
Thanks for the help!!