I am working to develop a Windows form Project, we should use a Product picture.
Every this working well, we use File.Exists() to check if the file already exists then copy the image to the product Image folder.
if (image.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(image.FileName))
{
_view.FirmLogo.Image = new Bitmap(image.FileName);
_view.LogoURL = Path.Combine(System.IO.Path.GetFullPath(#"..\..\"), #"Resources\ProductImage\", Path.GetFileName(image.FileName));
//
if (File.Exists(_view.LogoURL))
{
File.Delete(_view.LogoURL);
}
//File.Move(#"c:\test\SomeFile.txt", #"c:\test\Test\SomeFile.txt");
File.Copy(image.FileName, _view.LogoURL);
}
The Bug
when we try to update the same file it fired an error:
"because it is being used by another process.
Ex. if we upload pic1, everything is well, we try to change to pic2 great job.
but if we try to back the pic1 fired the error especially if it happens in the same seesion.
Related
I am using the JitBit Macro Recorder to create "bots" that save me a lot of time at work. This program can use the mouse and the keyboard and perform tasks by checking different if-options like "if image found on screen".
My newest "bot" is about 900 lines of commands long and I would like to make a log-file to find an error somewhere in there. Sadly, this program doesn't offer such an option, but it let's me use c# as a task. I have NO experience with c# but I thought, that this is easy to do for someone who has some experience.
If I click execute c# code, I get the following input field:
Important: This code MUST contain a class named "Program" with a static method "Main"!
public class Program
{
public static void Main()
{
System.Windows.Forms.MessageBox.Show("test");
}
}
Now I need two code templates:
1. Write a message to a "bot_log.txt" located on my desktop.
[19.05.2016 - 12:21:09] "Checking if item with number 3 exists..."
The number "3" changes with every run and is an exact paste of the clipboard.
2. Add an empty line to the same file
(Everything should be added to a new line at the end of this file.)
If you have no idea how to program in C#, then you should learn it,
if you want to use code provided from answers.
And if you want to generate timestamps and stuff then it's not done within minutes and I don't think someone writes the whole code just for your fitting. Normally questions should have at least a bit of general interest.
Anyway:
This works, if you have a RichTextTbox in your program.
Just do a new event (like clicking a button) and do this inside it.
(This was posted somewhere here too or on another site, with sligh changes)
public static void SaveMyFile(RichTextBox rtb)
{
// Create a SaveFileDialog to request a path and file name to save to.
SaveFileDialog saveLog = new SaveFileDialog();
// Initialize the SaveFileDialog to specify the RTF extention for the file.
saveLog.DefaultExt = "*.rtf";
saveLog.Filter = "RTF Files|*.rtf"; //You can do other extensions here.
// Determine whether the user selected a file name from the saveFileDialog.
if (saveLog.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
saveLog.FileName.Length > 0)
{
// Save the contents of the RichTextBox into the file.
try
{
rtb.SaveFile(saveLog.FileName);
}
catch
{
MessageBox.Show("Error creating the file.\n Is the name correct and is enough free space on your disk\n ?");
}
MessageBox.Show("Logfile was saved successful.");
}
}
I am having an issue with using the ImageLocation of a pictureBox. I went to:
Documents\VisualStudios\Projects\Program Name:
Then I create a new folder called images and within that folder i put the pictures(rock.png , paper.png )I intend to use. Keep in mind I can not load from the C drive, I have to turn this project in, so that it can work on any computer. Am I loading my images in the wrong location? or Am i accessing them wrong?
if (PlayerOne == Rock && PlayerTwo == Scissors)
{
ScoreOne++;
picture1.ImageLocation = #"images\rock.png";
picture2.ImageLocation = #"images\paper.png";
lblOneScore.Text = Convert.ToString(ScoreOne);
lblShowWinner.Text = " Player One Wins! ";
picture1.Load();
picture2.Load();
}
Instead of setting the ImageLocation property, try:
picture1.Load(#"C:\temp\pic.jpg");
The picturebox load method also accepts URL's (if you can't access drives and it needs to work on any PC without hardcoded UNC paths):
picture1.Load("http://i.stack.imgur.com/FmIGn.png");
Or use the app's location if you have packaged it with an image:
picture1.Load(Application.StartupPath + "\\a.jpg");
Or use a Resource file:
I would love to use resourceFile but I can not find it on Visual Studios 2015 only for 2013 and previous versions
It hasn't changed from VS2013 to VS2015, in your Winforms project, expand the Project Properties and double click on Resources.resx, then add an image:
picture1.Image = global::ProjectName.Properties.Resources.ImageName;
VisualStudios/Projects/fileName/filename/bin/Debug/create images folder and insert pictures in that folder and my original code posted works just fine
I have some problems while trying using WindowsInstaller library or Wix Microsoft.Deployment.WindowsInstaller.
I'm, getting exception that the file being used by the process and I cannot delete it even though I've closed all record,view and database and disposed them.
try
{
string currentDir = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
string msiPath = "PathTo\MyMSI.msi";
using (InstallPackage installPackage = new InstallPackage(msiPath, DatabaseOpenMode.ReadOnly))
{
string query = "SELECT * FROM Property WHERE Property = 'ProductVersion'";
using (View view = installPackage.OpenView(query))
{
view.Execute();
using (Record record = view.Fetch())
{
string version = record.GetString(2);
Console.WriteLine(version);
record.Close();
}
view.Close();
}
installPackage.Close();
}
File.Delete(msiPath);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
And still I get the following:
Access to the path 'PathTo\MyMSI.msi' is denied.
I've also tried with the object
Database
Any help will be appreciated.
I was able to figure out what is blocking the delete action.
It appears that the file was in read only.
I don't know why I got this kind of exception but the following solved it:
//removing read only from file in order to interact with it
FileInfo fileInfo = new FileInfo(msiPath);
if (fileInfo.IsReadOnly)
{
fileInfo.IsReadOnly = false;
}
Hope it will help others.
I appreciate everyone who helped here for your time.
Below are some steps you could follow for ur problem :
Wait a minute and try deleting the file again, sometimes Windows or the program using the file may still be closing and therefore still using the file you're attempting to delete.
Close and Explorer window and re-open.
Locate the program using the file and close it. If you're uncertain what program is using the file, close all programs until you're able to delete the file.
Try using unlocker, a free software program designed to unlock any file being used by Windows or other programs without restarting the computer.
Reboot the computer. If after closing all programs you're still unable to delete the file, it's likely that something in the background is still using the file.
If after rebooting the computer you're still unable to delete the file, boot the computer into Safe Mode and delete the file.
Thanks
(Please see the edit on the bottom of the question, if you do not want to read the whole story.)
Hi,
I am new to stackoverflow. Don’t get me wrong, I use it quite often. But up until now I never actually posted something. This is because I did not have something new/useful to say and my English is not that good. The first thing (might have) changed, the latter did not.
I ran into a problem at a customer's Windows 7 system quite recently. I was shipping a C# .Net 4.0 Windows Forms application via ClickOnce. Basically, it is an application that creates a bitmap file and shows it to the user. If the bitmap exists prior to the creation, the existing file gets deleted first. After that the new file is created and loaded by a PictureBox.
The following thing occurred at the customer’s system: After starting the application the first creation succeeds – the second and all following ones do not. The file cannot be deleted, because some process is blocking it. This process is the application itself.
System.IO.IOException: The process cannot access the file “filename” because it is being used by another process.
Well, of course that is nothing unusual. The thing is I tested the application on several systems. None showed this exception. And until now I am unable to see an code error.
So I looked a little bit closer on the customer’s system: The only difference I could find is, that they changed the users folder so that they are not located on the windows partition, but on a different one (C:\Users --> D:\Users). I searched for an instruction on the internet and did the same thing on one of my test systems. To my surprise I got the same exception when I ran my application on it.
With that I could change my code so that the exception does not occur anymore. But I do not understand why that is. So maybe there is something wrong with my code and the error just reveals itself under that special circumstances. Or maybe the code is okay and the reason lies somewhere else. I just hoped that you might be able to help me.
So here is some code I put together, that shows the same behavior. I used 3 buttons, an OpenFileDialog and a PictureBox on a Form. First thing to do is to choose an image file. By pressing one of the two remaining buttons it gets copied into the main folder of the application. After being copied it is shown by the PictureBox. By the way, it does not seem to matter if it is a ClickOnce-application or a “normal” one.
String m_FileName;
private void btnChooseFile_Click(object sender, EventArgs e) {
if(openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { // If file was chosen, set file name for later use and activate buttons.
m_FileName = "Test" + Path.GetExtension(openFileDialog1.FileName);
}
}
private void button1_Click(object sender, EventArgs e) {
// This is not working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image; // I was not sure, if maybe the pictureBox somehow prevents the disposing of the image, as long as it's assigned to it.
//this.pictureBox1.ImageLocation = null; // So I set them null, both the image and the image location.
//this.pictureBox1.Image = null;
//img.Dispose(); // Then I disposed the image.
this.pictureBox1.Image.Dispose(); // The short version. It is not working either way.
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true); // But still this is where the Exception occurs.
this.pictureBox1.Load(m_FileName);
}
private void button2_Click(object sender, EventArgs e) {
//This is working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image;
//this.pictureBox1.Image = null;
//img.Dispose();
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true);
pictureBox1.Image = Image.FromFile(m_FileName);
}
What happens now is the following: If I start the application and click button1 twice, I will get the exception (on the second click). If I start it and click button2 twice, I will not. If I start the application and click buttons1 first and after that button2, I will get the exception. So, the Picture.Load-Function somehow blocks the file, even if I dispose it.
When I searched on the internet, I found an article from microsoft: http://support.microsoft.com/kb/309482/en-us. But it does not hit the bull's eye.
Take into account, that both versions are working on all my test machines. I just get the exception when I change the users folder to a non-windows-partition.
Why is that? And where is the difference in the presented versions?
Edit
Okay, because of the first and only reaction so far, it seems to me, that it is still not clear, what really happens: If I take the above code, put it in a Windows Forms application, compile it and run it on different computers (at work, at home, does not matter) it works - both button1 and button2 (with the Click-functions linked to them) can be used as often as I like - no exception thrown. If I run the application on a computer, where I changed the users folder, and click button1 the second time - bam - IOException, file locked by process. Button2 works as long as I do not press button1.
The first answer implies, that I should get the locking on every system. But I DO NOT (as long as I do not change the users folder)! I tested it on every single computer I could get my hands on - no IOException. I set up a new system, just to rule out some special changes to the systems in my company - both buttonx_Click functions worked - no exception either. I even compiled the program on another computer - same behavior. The only three systems to throw that exception were the ones with the changed users folder.
So far I have no clue, why this difference in behavior occurs. Can somebody help me?
Anybody?
Yes, this is normal. Happens on any operating system, doesn't have anything to do with the Users folder location. The PictureBox.Load() method was intented to be used to load images from locations other than the file system. Like a web site. Which is slow, it avoids freezing the UI while the download is taking place.
It internally uses a FileStream when it discovers that the url you pass is actually a file and not a website name. This FileStream does not get disposed until the PictureBox itself is disposed or you call the Load() method again. A requirement because Image.FromStream() requires the stream to remain readable until the image is no longer used. It is this FileStream that keeps a lock on the file. Disposing the PictureBox.Image is not enough to also dispose the FileStream, the Image object doesn't know that it is being displayed inside a picture box.
There are several ways to solve this problem:
Use the Image property instead of Load(), assign it from Image.FromFile(). Disposing the Image now also releases the lock on the file. As you found out
Keep a dummy image around, one that perhaps displays a "Loading..." bitmap. Load() it first to release the lock on the file
Dispose the PictureBox and recreate it.
This works and unlocks the file
Image img= Image.FromFile(mypath);
Graphics g = pictureBox1.CreateGraphics();
g.DrawImage(img,0,0);
img.Dispose();
I see a lot of people coming up with some excessive ways to change the folder location on the fly with flajaxian multiple file upload control.
Was just wondering if the more experienced could take a look at the way I've come up with and let me know if there are any major issues I should be concerned about. (Assuming I have the proper error checking in place.)
I planned on initializing the control as seen below. :
<cc1:FileUploader ID="FileUploader1" runat="server" OnFileReceived="fileUploader_FileReceived" RequestAsPostBack="true">
</cc1:FileUploader>
(I RequestAsPostBack="true" as there are some other controls I need to check in my event handler)
I simply change the HttpFileCollection.SaveAs property in the fileUploader_FileReceived event. Since flajaxian does this one file upload at a time, we can expect that there is only 1 file in the collection (or else we could use a loop).
protected void fileUploader_FileReceived(object sender,
com.flajaxian.FileReceivedEventArgs e)
{
HttpFileCollection files = Request.Files;
// Change path to whichever folder I need
String TempFileName = "C:\\NEW\\PATH\\TO\\Folder\\" + files[0].FileName;
// Save the file.
files[0].SaveAs(TempFileName);
}
This implementation seems to work great as long as the folder is existing! I was just wondering if there is anything technically wrong with an implementation like this, again , assuming all error checking was in place.
Thanks!
A better way to do this would be to use an adapter, and over write the folder location in the
OnFileNameDetermining event. This way, we also get all the goodies with the adapter.
<cc1:FileUploader ID="FileUploader1" runat="server"` OnFileReceived="fileUploader_FileReceived" RequestAsPostBack="true">
<Adapters>
<cc1:FileSaverAdapter runat="server" FolderName="Ups" OnFileNameDetermining="fileUploader_FileDetermined" />
</Adapters>
</cc1:FileUploader>
In the file determined event, we can change the folder location programatically
protected void fileUploader_FileDetermined(object sender, com.flajaxian.FileNameDeterminingEventArgs e)
{
e.FileName = "C:\\NewFolder\\" + e.File.FileName;
}
We can use the FileReceived event to check if the folder exists, and if not, create it.
protected void fileUploader_FileReceived(object sender, com.flajaxian.FileReceivedEventArgs e)
{
int fileIndex = e.Index;
if (fileIndex == 0)
{
// We are on our first file, check if the new folder exists, if not, create it
}
}
What you are doing is fine, although, if you are saving files within the web site, consider using the MapPath method to create a physical folder from a virtual path within the web site
MapPath("/Images/User1")
This my mininal APSX implementation
<fjx:FileUploader ID="FileUploader1" runat="server" OnFileReceived="FileUploader2_FileReceived">
</fjx:FileUploader>
No adapters or folder is specified. When the FileRecevied event fires, I save files to a folder based on the Forms Authentication user name (names do not use characters not allowed in folder names).
Also note that the FileReceivedEventArgs has a reference to the (HTTP) file
e.File
The FileUploader control will show all files processed - you can even set the status code (e.g. 550) if there is an error, which is returned to the client.
Note that, the server call to the FileReceived event does not occur inside a nornal page postback, even if you specify
RequestAsPostBack="true"
So, a PagePreRender does not take place.
The only issue is, how do you perform any other processing at the client after the uploads complete (e.g. showing images uploaded).
Work I have in progress to this end is to use the client side event
FileStateChanged
When the last file is processed
if (file.state > Flajaxian.File_Uploading && isLast) {
I use JQuery to click a hidden submit button. The postback looks through session values stored when the files were saved, and renders back the images into a DIV.
However, an immediate submit causes issues with empty session inside the FileReceived event for some reason (I assume because the internal asynchronous call back has not completed). A pause of a few seconds before initiating the postback works OK.