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

変更するたびにこのように現在の壁紙を開く必要があるアプリを書いています。 私は最初に壁紙のパス(GetCurrentWallpaper)を取得するためにレジストリにアクセスし、FileSystemWatcherを使用して、壁紙が変更されたときにそれを行います。 奇妙なことに、それは一度しか動作しません。壁紙が2度目にアクセスされた場合(私がどれくらい待つかは関係ありません)、私のアプリはすでに使用中であるためファイルにアクセスできないとIOExceptionがクラッシュしました。 アプリを再起動すると、ファイルに再度アクセスできますが、上記のように1回だけアクセスできます。それ以外の場合はクラッシュします。 そのファイルにアクセスするためにできることはありますか?既に使用中のファイルを開く

編集:詳細コード:

  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

+0

usingブロックを終了する前に、Closeおよび/またはFlushを明示的に呼び出そうとしましたか? – Sascha

+0

あなたのコードをもっと投稿してください、私はあなたがどこか他の場所にオープンしていて、それを閉じるのを忘れていると確信しています。あなたは 'using'ブロックでそれを使用しているので、明示的に' .Close() 'する必要はありません。それは世話をしているので、他に何かがあると確信しています。 –

答えて

0

あなたはさらに読み取り操作用にファイルをリリースする予定よりもfs.Close()を使用している場合。

関連する問題