Deleting JPEG Not Allowed(Used By Another Process)

3

Question Edited!! This is an example of compilabile files to help you find my problem! I save some screenshots in a specific file. When i use function DeleteFile() it should delete first the contents and then the folder but then i get "that icon.jpg is used by another process"! (Either way to delete a folder it has to have no content!)

ImageExtensions.cs

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace name
{
    static class ImageExtensions
    {
        public static void SaveToFile(Image image,string path,ImageFormat format)
        {
            using (var stream = File.OpenWrite(path))
            {
                image.Save(stream, format);
            }

        }
    }
}

ScreenCapture.cs

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace name
{
    public class ScreenCapture
    {

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);

        [StructLayout(LayoutKind.Sequential)]
        private struct Rect
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetDesktopWindow();


        public static Image CaptureDesktop()
        {
            return CaptureWindow(GetDesktopWindow());
        }

        public static Bitmap CaptureActiveWindow()
        {
            return CaptureWindow(GetForegroundWindow());
        }


        public static Bitmap CaptureWindow(IntPtr handle)
        {
            var rect = new Rect();
            GetWindowRect(handle, ref rect);
            var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
            var result = new Bitmap(bounds.Width, bounds.Height);

            using (var graphics = Graphics.FromImage(result))
            {
               graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
            }

            return result;
        }
    }
}

AnotherFile.cs (Uses PrintScreen() )

public void PrintScreen()
{
    using (var image = ScreenCapture.CaptureDesktop())
    {
        ImageExtensions.SaveToFile(image, (file_images + ".jpg"), ImageFormat.Jpeg);
    }
}

Form1.cs (Main)

using ...
using ...

namespace name{

    public partial class Form1 : Form
    {
    const int MaxRetries = 3;
    const int DelayBetweenRetries = 1000;
    const int ERROR_SHARING_VIOLATION = unchecked((int)0x80070020);
    string file_images = my_path_of_images_file;

    Public Form1()
    {
        InitializeComponent();
        CreateFile();
    }

    private void Form1_Load(object sender, EventArgs e){}

    public void CreateFile()
    {
        if (!Directory.Exists(file_images))
        {
            DirectoryInfo di = Directory.CreateDirectory(file_images);
        }
    }


    public void DeleteFiles()
    {
         string[] filesToDelete = Directory.GetFiles(file_images);
         if (filesToDelete != null)
         {
            var files = filesToDelete.Where(x => Path.GetExtension(x).Contains(".jpg"));
                foreach (var file in files)
                {
                   var temp = file;
                   DeleteFile(temp); // Delete JPEG
                } 
            }
        Directory.Delete(file_images); // Delete Folder
    }


    public static void DeleteFile(string path)
    {
        for (int i = 0; i < MaxRetries; ++i)
        {
            try
            {
                File.Delete(path);
            }
            catch (IOException e)
            {
                // You may also sleep whatever the error is...
                if (Marshal.GetHRForException(e) == ERROR_SHARING_VIOLATION)
                {
                    Thread.Sleep(DelayBetweenRetries);
                    continue;
                }
                throw;
             }
          }
      }
    } // End Of Main.cs
} // End Of Namespace
c#
jpeg
asked on Stack Overflow Mar 31, 2016 by Antonios Tsimourtos • edited Apr 1, 2016 by Antonios Tsimourtos

1 Answer

0

I have had this problem before and I solved it by copying the image data from the filestream into a memorystream, then loading the image from it. Similarly with the saving the image. This way, even if Image keeps a reference to the source or saved stream, it is not a physical file.

A more complete solution: https://siderite.dev/blog/imagefromstream-or-imagefromfile.html

try:

using (var ms=new MemoryStream()) {
  image.Save(ms,format);
  File.WriteAllBytes(path,ms.ToArray());
}

I wrote this inline, so tweak it if it doesn't work exactly.

answered on Stack Overflow Mar 31, 2016 by Siderite Zackwehdex • edited Dec 15, 2019 by Siderite Zackwehdex

User contributions licensed under CC BY-SA 3.0