How to save Image changes to source file? [duplicate] - c#

I'm trying to programmically delete a file, but the file is apparently being used by another process (which happens to be my program). Basically, the program loads images from a folder by using FromUri to create a Bitmap, which is then loaded into an Image array, which in turn becomes the child of a stackpanel. Not very efficient, but it works.
I've tried clearing the stackpanel's children, and making the images in the array null, but I'm still getting the IOException telling me that the file is being used by another process.
Is there some other way to remove the file from my application's processes?

it may be Garbage Collection issue.
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
File.Delete(picturePath);

In order to release an image file after loading, you have to create your images by setting the BitmapCacheOption.OnLoad flag. One way to do this would be this:
string filename = ...
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(filename);
image.EndInit();
Although setting BitmapCacheOption.OnLoad works on a BitmapImage that is loaded from a local file Uri, this is afaik nowhere documented. Therefore a probably better or safer way is to load the image from a FileStream, by setting the StreamSource property instead of UriSource:
string filename = ...
BitmapImage image = new BitmapImage();
using (var stream = File.OpenRead(filename))
{
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
}

Another way is to delete file. Load your file using FileStream class and release an file
through stream.Dispose();
it will never give you the Exception "The process cannot access the file '' because it is being used by another process."
using (FileStream stream = new FileStream("test.jpg", FileMode.Open, FileAccess.Read))
{
pictureBox1.Image = Image.FromStream(stream);
stream.Dispose();
}
// delete your file.
File.Delete(delpath);

var uploadedFile = Request.Files[0]; //Get file
var fileName = Path.GetFileName(uploadedFile.FileName); //get file name
string fileSavePath = Server.MapPath(fileName); //get path
uploadedFile.SaveAs(fileSavePath); //saving file
FileInfo info = new FileInfo(fileSavePath);//get info file
//the problem ocurred because this,
FileStream s = new FileStream(fileSavePath, FileMode.Open); //openning stream, them file in use by a process
System.IO.File.Delete(fileSavePath); //Generete a error
//problem solved here...
s.Close();
s.Dispose();
System.IO.File.Delete(fileSavePath); //File deletad sucessfully!

I had the similar issue. The only difference was that I was using Binding(MVVM Pattern). Nothing much worked then I removed everything and tried with Binding Mode=OneWay along with GC.Collect() before calling File.Delete(path) and it worked finally.

I had the same issue. The problem I had was with the openFileDialog and saveFileDialog having the following set:
MyDialog.AutoUpgradeEnabled = false;
I commented out that line and it was resolved.

In my case, I started a new process of devenv.exe opening a temporary solution file. After the process was ended, I found I could not delete the directory for few minutes. Checking with "resmon", resource monitor, I found it was a executable called PerfWatson2.exe that was using the temp file. Looking at the site, PerfWatson is actually a Visual Studio Customer Experience Improvement Program from MicroSoft. It will lock the file or directory you temporarily used even after you have ended the VS IDE.
The solution is to disable the Visual Studio Customer Experience Improvement Program, see this. This shoudln't be an issue after your app is publihsed. But it is quite annoying during debuging.

Related

Out of memory crash when trying to change image?

(C#) I get an out-of-memory crash when I try setting the image of a "picture box" with one opened from a file.
My code:
string file = openImageBox.Text; // Our file
if (File.Exists(file))
{
File.Open(file, FileMode.Open); // Open the file for use.
Output.Text = "File Open Success!"; //Informing the user on how sucessful they are.
Output.ForeColor = System.Drawing.Color.Black;
Image img = Image.FromFile(file);
Display.Image = img;
}
Probably not the right answer (who knows.. it could be causing you all sorts of issues).
You don't need to "Open the file for use". This is holding a handle to the file you don't need. Just call Image.FromFile directly and it will work fine.
So remove this:
File.Open(file, FileMode.Open); // Open the file for use.
EDIT:
For completeness (and to help you learn), you need to store a reference to the stream if you want to close it. What I told you to remove above holds a handle to the file. The file is essentially open now.. until you close it.
For other code (where you're not using a method like Image.FromFile), you would either store a handle to the file so you can close it.. or use a using statement to close it for you.
Option A:
var stream = File.Open(file, FileMode.Open);
// do stuff here
stream.Close();
Option B (preferred):
using (var stream = File.Open(file, FileMode.Open)) {
// do stuff here
} // stream.Close automatically called for you

C# - WPF how to unreference a BitmapImage so I can delete the source file?

This seems like a fairly simple issue, but I can't seem to figure a way to work around it.
In a WPF window I have an image, image_small_pic. In the associated C# file I set the value of that using this code:
Uri src = new Uri(image_source, UriKind.RelativeOrAbsolute);
small_image_bmp = new BitmapImage(src);
image_small_pic.Source = small_image_bmp;
Where small_image_bmp is a public BitmapImage object. But then if then, later on, if I change small_image_bmp to another file and reassign image_small_pic.Source, then the original image is still locked and I can't delete it. Even if I try later it's still locked. Any thoughts how I can free this up?
Check out this article. There's some odd behaviour with WPF images that you're coming across. The solution is to read in the bytes yourself and then create an image based on them, since if you let the framework handle it, the file will remain locked.
Uri src = new Uri(image_source, UriKind.RelativeOrAbsolute);
var small_image_bmp = new BitmapImage();
small_image_bmp.BeginInit();
small_image_bmp.CacheOption = BitmapCacheOption.OnLoad;
small_image_bmp.UriSource = src;
small_image_bmp.EndInit();
image_small_pic.Source = small_image_bmp;

Can't open an image in WPF app

In my application I want to display some pictures (I need to have them stored in a list). I have problem with opening them. Firstly, I made a directory Images (using VS). Next I loaded pictures to this folder (also in VS).
I wanted to open one of them like here:
http://msdn.microsoft.com/en-us/library/aa970062.aspx
Stream imageStreamSource = new FileStream("Images\bulbOff.png", FileMode.Open, FileAccess.Read, FileShare.Read);
PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
And then while trying to run the program, I got:
XamlParseException
with hardly any information.
For sure the first line is causing the problem, because the problem disappears only when I delete it.
I tried to do it also like:
Uri myUri = new Uri("Images\bulbOff.png", UriKind.RelativeOrAbsolute);
PngBitmapDecoder decoder2 = new PngBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource2 = decoder2.Frames[0];
with the same result.
I also tried to copy the image to main folder of app (in SolutionView). When I tried to get "\bulbOff.png" the result was the same.
When I tried to get "bulbOff.png" I got
XamlParseException
again, but with some info - there were hints that path could be wrong.
If you want to provide a BitmapImage...
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(#"..\Images\DocumentAccess_16x16.png", UriKind.Relative);
image.EndInit();
...where Images is a folder within your project.
Try to change your image and code to a jpg extension. Seriously.

The process cannot access the file because it is being used by another process

I am getting binary data from a SQL Server database field and am creating a document locally in a directory my application has permissions. However I am still getting the error specified in the title. I have tried numerous suggestions posted on the web including those suggested in previous posts on Stackoverflow. I have also used ProcessExplorer > Find Handle to locate the lock and it returns nothing as if the file is not locked.
I am using the code below to save the file to the file system and I then try to copy this file to a new location later in the application process within another method. It is this copy method that takes the path of the newly created file that throws the exception.
The file itself is created with its content and i can open it through Windows Explorer without any problems.
Am I missing something completely obvious? Am I creating the file correctly from the database? Any help on solving or better diagnosing the problem would be much appreciated.
// Get file from DB
FileStream fs = new FileStream(
"C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
fs.Flush();
fs.Close();
fs.Dispose();
// Copy file
File.Copy(sourceFileName, destinationFilename, true);
Try adding a call to GC.Collect() after you have disposed of your streams to force the garbage collector to clean up.
// Get file from DB
using(FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write))
using(BinaryWriter br = new BinaryWriter(fs))
{
br.Write("BinaryDataFromDB");
fs.Flush();
}
//Force clean up
GC.Collect();
// Copy file
File.Copy(sourceFileName, destinationFilename, true);
change your code as follows, the problem is that the the filestream isn't being garbage collected when you need it to:
// Get file from DB
using (FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write))
{
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
fs.Flush();
fs.Close();
}
// Copy file
File.Copy(sourceFileName, destinationFilename, true);
What about using?
string source = #"C:\myTempDirectory\myFile.doc";
using(FileStream fs = new FileStream(
source, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read))
{
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
}
File.Copy(sourceFileName, destinationFilename, true);
EDIT: Try to inform a FileShare.Read permission.
I came to understand that though the error debugger says that the error lies in this code.. But that isn't where the error is..
I faced a similar issue and I came with this solution.. consider all the posts above..
May be it may help some one..
I used the Image to show it in a picturebox after retreiving from Database and saving it as "temp.bmp" using normal coding without using "using" keyword using this code at first:
PictureBox1.Image = Image.FromFile("temp.bmp");
and it raised and error and I really didn't got head and tail of the error.. and so I came up with this solution.
Instead of assigning it directly try this code:
Bitmap img;
using (Bitmap bmp = new Bitmap("temp.bmp"))
{
img = new Bitmap(bmp);
}
pictureBox1.Image = img;
coming to the filestream part I just used normal code as follows:
FileStream fs = new FileStream("filepath",FileMode.Create);
and it worked like a piece of cake
It really helped
Is it that Filestream and BinaryWriter cannot be used at the same time? For instance, a streamwriter and a streamreader cannot both be called on the same file. However, this doesn't make sense, as far as I know, it should not in this case. Perhaps try closing br as well?
Try disposing your BinaryWriter object before doing the copy.
Is there a background process such as antivirus or file-system indexing locking the file just long enough to cause problems with your application? Try pausing for 3 seconds to see if your problem disappears.
using System.Threading;
fs.Dispose();
Thread.Sleep(3000);
// Copy file
This was what I did:
Stream stream = new MemoryStream();
var tempStream = new FileStream(pathToFile, FileMode.Open);
tempStream.CopyTo(stream);
tempStream.Close();
then use stream object wherever you want.
I seem to encounter this only after I have published an application. If you close the message box and try again to debug, nothing will happen.
MS Help says to get all the way out of Visual Studio and restart it. Its easier to bring up Task manager and end the process. Its name will be the solution name followed by ".vshost" (e.g. project name: PLC.sln; process name: PLC.vshost.exe). The process will restart automatically. In Windows 7 one could usually see something happen when ending a process. But in 10 the Task Manager window rarely changes.
I get this message when I try testing a program after changing code. Apparently the .exe is not closed when one stops debugging and the error occurs when VS tries to write a newly complied exe file. I sometimes have to end the process twice to keep the error message from coming back. (I have to encounter the error twice; ending the process twice and then rerunning doesn't help.)
This is a bug in Visual Studio.

Using BitmapFrame for metadata without locking the file

I've found the common way to get image metadata in WPF is to create a BitmapFrame object and inspect the Metadata property on it. However I can't seem to create a BitmapFrame object that fulfills these two requirements:
Does not lock the file
Does not throw weird, undocumented exceptions when given certain files
Using these lines seems to create the BitmapImage reliably:
BitmapFrame.Create(new Uri(imageName));
BitmapFrame.Create(new Uri(imageName), BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
However they leave the file locked for an indeterminate amount of time. There is no dispose method on the BitmapFrame as far as I can tell.
This keeps the file from being locked:
BitmapFrame.Create(new Uri(imageName), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
However on Vista it throws ArgumentExceptions and InvalidOperationExceptions on certain files and on Win7 it throws FileFormatExceptions and IOExceptions. This makes me think that caching the BitmapFrame is unsupported/untested.
Can you get metadata from an image in WPF without leaving a lock on the file for an indeterminate length of time?
Have you tried using a converter approach? For example, my Intuipic application does this. See BitmapFrameConverter for details on loading without locking, and BitmapOrientationConverter for getting at metadata.
I don't know if an answer at this time can still be useful to anybody but since I got here only today, I assume that somebody else may be interested.
I had a similar problem when trying to use BitmapFrame to test if an image is valid, then trying to rename the image file. With this code, the image is locked and the Move command does not work:
bool isImageValid = true;
try
{
BitmapFrame bmpFrame = BitmapFrame.Create(new Uri("C:\\Images\\Test.jpg"));
}
catch
{
isImageValid = false;
}
File.Move("C:\\Images\\Test.jpg", "C:\\Images\\Test0.jpg");
However, when I first read the image file in a file stream, the file is released as soon as the using block is done and the Move command works:
bool isImageValid = true;
try
{
using (FileStream fs = new FileStream("C:\\Images\\Test.jpg", FileMode.Open))
{
BitmapFrame bmpFrame = BitmapFrame.Create(fs);
}
}
catch
{
isImageValid = false;
}
File.Move("C:\\Images\\Test.jpg", "C:\\Images\\Test0.jpg");
Try either bitmapImage.StreamSource.Dispose() or bitmapImage.Freeze();

Categories