不允许删除 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());
}
我写了这个内联的,所以如果它不能正常工作,请调整它。
问题已编辑!!这是可编译文件的示例,可帮助您找到我的问题! 我将一些屏幕截图保存在特定文件中。 当我使用函数 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());
}
我写了这个内联的,所以如果它不能正常工作,请调整它。