【问题标题】:Delete File Used By Other Process删除其他进程使用的文件
【发布时间】:2019-12-19 06:17:49
【问题描述】:

我正在尝试创建一个 C# 应用程序,它加载一个 powerpoint 并使每张幻灯片成为存储在 BitmapImages 列表中的 JPG。用户应该能够加载另一个 powerpoint,加载时会删除文件夹中的每个其他 JPG。目前,我无法删除 JPG,因为它们“正被另一个进程使用”,而这恰好是这个应用程序。我该如何解决这个问题?

foreach (ISlide slide in presentation.Slides)
{
             System.IO.Stream imageStream = slide.ConvertToImage(Syncfusion.Drawing.ImageFormat.Jpeg);
             System.Drawing.Image convertedImage = System.Drawing.Image.FromStream(imageStream);

             if (!System.IO.File.Exists(picsPath + "\\Slide_" + slide.SlideNumber + ".jpg"))
                  convertedImage.Save(picsPath + "\\Slide_" + slide.SlideNumber + ".jpg");
             else
             {
                        try
                        {
                  System.IO.File.Delete(picsPath + "\\Slide_" + slide.SlideNumber + ".jpg");               
                  convertedImage.Save(picsPath + "\\Slide_" + slide.SlideNumber + ".jpg");
             }
                  catch (Exception df){Console.WriteLine(df.StackTrace);}
             }
             bitmap = new BitmapImage();
             bitmap.BeginInit();
             bitmap.UriSource = new Uri(picsPath + "\\Slide_" + slide.SlideNumber + ".jpg");
             bitmap.CacheOption = BitmapCacheOption.OnLoad;
             bitmap.EndInit();
             VisualAidPPT.Add(bitmap);
             convertedImage = null;
}

【问题讨论】:

  • 这是因为 jpg 文件被您之前对其执行的操作锁定。使用 .Dispose() 释放文件处理程序
  • 您可以使用来自 sysinternals 的handle.exe,它会为您提供使用指定文件的进程。您可以解析其输出并终止该进程,然后您可以删除您的文件。
  • 为什么要使用System.Drawing.Image.FromStream(即WinForms)而不是通过将imageStream 分配给其StreamSource 属性来直接加载BitmapImage?似乎根本不需要保存 JPEG 文件。
  • 感谢大家的帮助。现在,当我显示一个新的 ppt 时,前几张幻灯片仍然显示从上次加载的 ppt 中显示,但最后几张来自新更新的幻灯片。检查文件夹中的文件,它们都是新更新的。有人知道为什么会这样吗?
  • @Clemens 我使用了 StreamSource 属性,但是当我没有将 UriSource 设置为文件的位置时会引发异常

标签: c# wpf process


【解决方案1】:

您根本不需要编写任何图像文件。

直接使用slide.ConvertToImage返回的Stream来加载一个BitmapImage即可:

foreach (var slide in presentation.Slides)
{
    var bitmap = new BitmapImage();

    using (var imageStream = slide.ConvertToImage(Syncfusion.Drawing.ImageFormat.Jpeg))
    {
        imageStream.Position = 0;

        bitmap.BeginInit();
        bitmap.StreamSource = imageStream;
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.EndInit();
    }

    VisualAidPPT.Add(bitmap);
}

编辑:如果上述方法不起作用,您仍然可以解码 System.Drawing.Image 并将其保存到 MemoryStream:

foreach (var slide in presentation.Slides)
{
    var bitmap = new BitmapImage();

    using (var imageStream = slide.ConvertToImage(Syncfusion.Drawing.ImageFormat.Jpeg))
    using (var image = System.Drawing.Image.FromStream(imageStream))
    using (var memoryStream = new MemoryStream())
    {
        image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
        memoryStream.Position = 0;

        bitmap.BeginInit();
        bitmap.StreamSource = memoryStream;
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.EndInit();
    }

    VisualAidPPT.Add(bitmap);
}

【讨论】:

  • 我收到异常 System.NotSupportedException: 找不到适合完成此操作的成像组件
  • 你设置Position = 0了吗?
  • 查看编辑后的答案。它在加载 BitmapImage 之前将图像流复制到 MemoryStream。
  • 仍然得到同样的异常;找不到组件
  • 您可以尝试使用与Syncfusion.Drawing.ImageFormat.Jpeg 不同的格式吗?例如。 PNG?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
相关资源
最近更新 更多