One of our more regular contributors to EVEMon posted on our forums showing that the application was incapable of updating cached files (specifically images), after a bit testing I discovered the following Exception was being thrown when trying to overwrite the file in question:
System.IO.IOException: The process cannot access the file 'path\filename' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite) at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite) at EVEMon.Common.FileHelper.OverwriteOrWarnTheUser(String srcFileName, String destFileName) in EVEMon.Common\FileHelper.cs:line 108 at EVEMon.Common.FileHelper.OverwriteOrWarnTheUser(String destFileName, Func`2 writeContentFunc) in EVEMon.Common\FileHelper.cs:line 82 at EVEMon.Common.Controls.CharacterPortrait.SavePortraitToCache(Image newImage) in EVEMon.Common\Controls\CharacterPortrait.cs:line 248
After a bit of searching around I discovered a post on StackOverflow identifying that System.Drawing.Bitmap(string filename) would lock the filename until the Bitmap was disposed of. The post presented a solution but no code, A bit of further searching confirmed my expectation that Image.FromFile(string filename) was subject to the same locking behaviour:
The file remains locked until the Image is disposed.
A bit more searching identified another post on StackOverflow which gave me the basic syntax and structure for the code I was going to need to implement this in EVEMon. The final code looks like this:
MemoryStream stream = new MemoryStream(); byte imageBytes = File.ReadAllBytes(cacheFileName); stream.Write(imageBytes, 0, imageBytes.Length); stream.Position = 0; var image = Image.FromStream(stream); return image;
It appears that GDI+ will lock any image that is loaded into a control in WinForms and WPF, several comments on StackOverflow and byte.com suggested that even disposing of the control and the FileStream was not a reliable way of being able to write to the file so the above method is seems to be be the best solution all round.