不允许删除 JPEG(被另一个进程使用)

Deleting JPEG Not Allowed(Used By Another Process)

问题已编辑!!这是可编译文件的示例,可帮助您找到我的问题! 我将一些屏幕截图保存在特定文件中。 当我使用函数 DeleteFile() 时,它应该先删除内容,然后删除文件夹,然后我得到 "that icon.jpg is used by another process"! (无论哪种方式删除文件夹都必须没有内容!)

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

我以前遇到过这个问题,我通过将图像数据从文件流复制到内存流,然后从中加载图像来解决它。与保存图像类似。这样,即使 Image 保留对源或保存流的引用,它也不是物理文件。

更完整的解决方案:https://siderite.dev/blog/imagefromstream-or-imagefromfile.html

尝试:

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

我写了这个内联的,所以如果它不能正常工作,请调整它。