2012-04-22 42 views
3
using (System.IO.FileStream fs = File.Open(GetCurrentWallpaper(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { 

我正在写一个应用程序,每次更改时都需要打开当前壁纸。 我第一次访问注册表获取壁纸的路径(GetCurrentWallpaper),并使用FileSystemWatcher在壁纸更改时使用壁纸做东西。奇怪的是,它只能使用一次。如果墙纸第二次被访问(无论等待多长时间无关紧要),我的应用程序会崩溃并出现IOException,告诉我无法访问该文件,因为它已被使用。 如果我重新启动应用程序,它可以再次访问该文件,但是,如上所述,只有一次。否则它崩溃。 有什么我可以做的,以获得访问该文件?打开已在使用的文件

编辑:更多的代码:

  using (System.IO.FileStream fs = File.Open(GetCurrentWallpaper(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { 
       using (Bitmap orig = (Bitmap)Bitmap.FromStream(fs, true, false)) { 
        int width = Convert.ToInt32(orig.Width/3); 
        int height = Convert.ToInt32(orig.Height/3); 

        Rectangle rect = new Rectangle(0, 0, width, height); 
        using (Bitmap bmp = new Bitmap(width, height)) { 
         using (Graphics bmpg = Graphics.FromImage(bmp)) { 
          col = ColorHelper.CalculateAverageColor(bmp, true, 20); 
          fs.Flush(); 
          fs.Close(); 
         } 
        } 
       } 
      } 

//this is in the ColorHelper class 
public static System.Drawing.Color CalculateAverageColor(Bitmap bm, bool dropPixels, int colorDiff) { 
     int width = bm.Width; 
     int height = bm.Height; 
     int red = 0; 
     int green = 0; 
     int blue = 0; 
     int minDiversion = colorDiff; 
     int dropped = 0; 
     long[] totals = new long[] { 0, 0, 0 }; 
     int bppModifier = bm.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb ? 3 : 4; 

     BitmapData srcData = bm.LockBits(new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, bm.PixelFormat); 
     int stride = srcData.Stride; 
     IntPtr Scan0 = srcData.Scan0; 

     unsafe { 
      byte* p = (byte*)(void*)Scan0; 

      for (int y = 0; y < height; y++) { 
       for (int x = 0; x < width; x++) { 
        int idx = (y * stride) + x * bppModifier; 
        red = p[idx + 2]; 
        green = p[idx + 1]; 
        blue = p[idx]; 

        if (dropPixels) { 
         if (Math.Abs(red - green) > minDiversion || Math.Abs(red - blue) > minDiversion || Math.Abs(green - blue) > minDiversion) { 
          totals[2] += red; 
          totals[1] += green; 
          totals[0] += blue; 
         } else { 
          dropped++; 
         } 
        } else { 
         totals[2] += red; 
         totals[1] += green; 
         totals[0] += blue; 
        } 
       } 
      } 
     } 

     int count = width * height - dropped; 
     int avgR; 
     int avgG; 
     int avgB; 

     if (count > 0) { 
      avgR = (int)(totals[2]/count); 
      avgG = (int)(totals[1]/count); 
      avgB = (int)(totals[0]/count); 
     } else { 
      avgR = (int)(totals[2]); 
      avgG = (int)(totals[1]); 
      avgB = (int)(totals[0]); 
     } 

     bm.UnlockBits(srcData); 
     return System.Drawing.Color.FromArgb(avgR, avgG, avgB); 
    } 
+0

墙纸是否在使用区块结束之前更改? – taylonr 2012-04-22 16:33:06

+0

您是否尝试在离开使用区块之前明确调用Close和/或Flush? – Sascha 2012-04-22 16:33:24

+0

请张贴更多你的代码,我敢肯定你打开它在别的地方,忘记关闭它。既然你在'use'块中使用它,你不必明确地'.Close()',这是照顾好的,所以我很确定还有其他事情正在进行。 – 2012-04-22 16:35:05

回答

0

如果使用fs.Close()比你将发布进一步的读取操作的文件。