Search code examples
c#.netprocessfilestream

Why is the FileMode.Create being used in another process?


So I am currently developing a simple application that will take a screenshot of my desktop and then I can send it quickly though an email to a friend or family.

Here is the thing though.. When i press the Inilizalize button it runs through these methods..

        screenshot();
        setImage();
        saveScreenshot();
        sendScreenImage();

It takes a screenshot > sets the screenshot as the source in a image container > saves whats in the image container > sends it to who ever I want to send it to.
Simple right?

It all works great, Lets say I just run through taking the picture and saving it, it can replace (overwrite) the old one everytime I press

screenshot > set image > save screenshot

but as soon as I send it (add the sendScreenImage(); method) I cant overwrite the old image anymore because it says that that the process is being used

Error message: The process cannot access the file because it is being used by another process.

and its always throwing me that error in the same place which would be at this line

using (FileStream stream = new FileStream(path, FileMode.Create))

in saveScreenshot();

--QUESTION--

Whats using the process? And do I need to multithread the thing thats using the process or can I just cancel it?

using System;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.Threading;
using System.Net.Mail;
using System.Net;
using System.IO;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Drawing;
using System.Windows.Media;
using System.Drawing.Imaging;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Interop;
using System.Windows.Threading;
using WPFCSharpWebCam;

namespace WebcamApplication
{
    /// <summary>
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }


        #region methods
        private void initializeToolBtn_Click(object sender, RoutedEventArgs e)
        {
            screenshot();
            setImage();
            saveScreenshot();
            sendScreenImage();
        }
        private void screenshot()
        {
            SendKeys.SendWait("{PRTSC}");
        }

        private void setImage()
        {
            System.Windows.Clipboard.GetImage();
            var clipboardImage = System.Windows.Clipboard.GetImage();
            image.Source = clipboardImage;
        }


        private void saveScreenshot()
        {
            try
            {
                string path;
                path = "%AppData%\\image.png"; // collection of paths
                path = Environment.ExpandEnvironmentVariables(path);

                var encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create((BitmapSource)image.Source));
                using (FileStream stream = new FileStream(path, FileMode.Create))
                    encoder.Save(stream);
                System.Windows.MessageBox.Show("Replaced the old screenshot");
                return;
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(" saveScreenshot() went wrong " + ex.ToString());
            }
        }

        private void sendScreenImage()
        {
            try
            {
                System.Windows.Clipboard.GetImage();
                var clipboardImage = System.Windows.Clipboard.GetImage();
                image.Source = clipboardImage;

                string path;
                path = "%AppData%\\image.png"; // collection of paths
                path = Environment.ExpandEnvironmentVariables(path);


                MailMessage msg = new MailMessage();
                msg.From = new MailAddress(emailfromTextbox.Text, "Screenshot Image");
                msg.To.Add(new MailAddress(emailTextbox.Text));
                msg.Subject = "SCreenshot Image";
                msg.Body = clipboardImage.ToString();
                msg.IsBodyHtml = true;

                AlternateView plainView = AlternateView.CreateAlternateViewFromString("This is my plain text content, viewable by those clients that don't support html", null, "text/plain");
                AlternateView htmlView = AlternateView.CreateAlternateViewFromString("Here is an embedded image.<img src=cid:companylogo>", null, "text/html");

                //create the LinkedResource(embedded image)
                LinkedResource logo = new LinkedResource(path);
                logo.ContentId = "image.png";
                //add the LinkedResource to the appropriate view

                htmlView.LinkedResources.Add(logo);

                msg.AlternateViews.Add(plainView);
                msg.AlternateViews.Add(htmlView);


                SmtpClient smtp = new SmtpClient();
                smtp.Host = "smtp.gmail.com";
                smtp.Port = 587;
                smtp.Credentials = new NetworkCredential(emailTextbox.Text, emailpasswordTextbox.Text);
                smtp.EnableSsl = true;
                smtp.Send(msg);
                System.Windows.MessageBox.Show("Done");
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.ToString(), "GMAIL Error" + ex.ToString());

            }
        }

Solution

  • The LinkedResource owns a file stream to read the attachment.

    You need to dispose that in a using block after you send the email.