Hi all,
thanking you in advance for any assistance given.
I have a program that uses an external file on first run, but after that is not needed. I would like to know how I can make my program.cs wait for a form to be closed before deleting the external file.
Currently, my code to delete the file is located as the last instruction in the program.cs and is as below :
System.IO.FileInfo fidel = new FileInfo("email.txt");
fidel.Delete();
}
}
}
But the program.cs runs right through to this line, not waiting for the form to be closed, this throws up a windows error telling me that it can't delete the file as it is still in use by the form.
I'm sorry for this being so dumb, but I can't find any info as to how to do this.
Thanks again
Andy
Loading
Mamta MPosted Sep 7, 2010, 11:41 PM
First of all sorry for rushing off yest. After I posted my reply to you in a hurry I had to rush to catch a bus and couldnt login thereafter. I looked at all the replies so far and also your new error. I recreated your entire app at my end and tested it. With some tweaking, it's working fine. You dont need to include System.IO while using FileInfo becauase you have already written a using statement for the namespace at the top:
using System.IO;
As for the other modification I made it was wrt reader.Close(). It needs to be placed right after you finish reading the file.
See the final code below, it's working smoothly without any hitch and the file gets deleted too.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Threading;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
SerialPort sp = new SerialPort();
string input = "";
public Form1()
{
InitializeComponent();
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
string s = System.Environment.CurrentDirectory + "\\Email.txt";
MessageBox.Show(s);
}
//
//
//Code in here to send message out
//
private void Form1_Load(object sender, EventArgs e)
{
lblStatus.Text = "";
cmbRecipient.DropDownStyle = ComboBoxStyle.DropDownList;
cmbBoxPorts.DropDownStyle = ComboBoxStyle.DropDownList;
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
cmbBoxPorts.Items.Add(port);
}
try
{
cmbBoxPorts.SelectedIndex = 0;
}
catch { }
try
{
DataTable table = new DataTable();
DataColumn colEmail = new DataColumn("Email");
DataColumn colRecipient = new DataColumn("Recipient");
table.Columns.Add(colEmail);
table.Columns.Add(colRecipient);
StreamReader reader = new StreamReader(System.Environment.CurrentDirectory + "\\Email.txt");
do
{
Console.WriteLine(reader.ReadLine().Split(','));
table.Rows.Add(reader.ReadLine().Split(','));
}
while (reader.Peek() != -1);
// Close the reader here
reader.Close();
cmbRecipient.DataSource = table;
cmbRecipient.DisplayMember = "Email";
cmbRecipient.ValueMember = "Recipient";
cmbRecipient.SelectedIndex = 0;
}
catch
{
MessageBox.Show("ERROR: Unable to read txt file.\r\nCreate a 'Email.txt' file in the following format...\r\n\r\n,Please /Select Recipient\r\[email protected],Andy R\r\[email protected],Brian N");
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
FileInfo fidel = new FileInfo("Email.txt");
fidel.Delete();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
MessageBox.Show("Version 1.0\r\nE-mailer.");
}
}
}
Posted Sep 8, 2010, 1:27 AM
Thanks ever so much for all your OUTSTANDING assistance and patience.
Mamta:
Hi Mamta,
you are FANTASTIC! Thanks heaps for all the trouble you've gone to assist me in this learning.
Your code and explanations were SPOT-ON correct, thank you so very much.
Sam:
Hi Sam,
Thanks again, I am very keen (even for an old man that I am) to learn how to program, so I'm going to look for some good books as you suggest.
Lizard:
Hi Lizard,
Thanks heaps for your clear and concise explanation of the root cause, it made my understanding of Mamta's code very easy indeed.
Again, thank you to everyone who helped with this, I hope it will be of use to other beginners like me in the future.
Cheers
Andy
theLizardPosted Sep 8, 2010, 12:00 AM
Sam HobbsPosted Sep 7, 2010, 11:51 PM
Posted Sep 7, 2010, 9:02 PM
thanks heaps for all your help, I really do appreciate it.
Sorry for taking so long to reply, it was 2am and I needed to sleep.
Tanmay:
Thanks Tanmay,
I put that code where you said and the first time I ran the debugger, it worked fine, but after that first time, it now throws up this error:
System.IO.IOException was unhandled
Message="The process cannot access the file 'Email.txt' because it is being used by another process."
Source="mscorlib"
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileInfo.Delete()
at MyMessenger.Form1.Form1_FormClosing(Object sender, FormClosingEventArgs e) in E:\MyMessengerProject\Source\MyMessenger\Form1.cs:line 223
at System.Windows.Forms.Form.OnFormClosing(FormClosingEventArgs e)
at System.Windows.Forms.Form.WmClose(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Form.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmSysCommand(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Form.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmNcButtonDown(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at MyMessenger.Program.Main() in E:\MyMessengerProject\Source\MyMessenger\Program.cs:line 118
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
My program only has one form (Form1) that sends out a generic message, handled by program.cs. When the user is finished sending out the generic messages, they simply close the form with the standard windows close (X) button on top right.
I guessing that this is causing the trouble I'm getting now?
Does the above error message help anyone understand what I need to do to fix this problem?
Sam:
Sorry Sam,
I am an ABSOLUTE beginner at programming; this is my first attempt to write anything other than a rather simple MS Access database (I know, that's not programming) so you'll understand why my post is rather scattered.
As for the System.IO line, I got that code from a tutorial on this site, I really don't understand how to use it properly although I can understand it's uses the Input/Output of the System.
Would you mind letting me know how it should be written? Does this look correct:
System.IO.FileInfo fidel = new System.IO.FileInfo("Email.txt");
fidel.Delete();
When I run debugger for both ways, it compiles but throws up the same error when I close the form (see above error), so I'm guessing both work, just the code you suggest may be more correct (or specific)????
As for setting events via properties, to be honest; NO, I don't, but I'll start playing around and see if I can get the gist of that. In the meantime, if anyone has any helpful advice about this, I'd be VERY appreciative.
Dipal:
Thanks Dipal,
I've just found out how to copy the error info from the debugger, please see above.
And Yes; I agree, Sam has given some excellent advice, I'm hoping to learn heaps from following up on his suggestions.
Thanks heaps everyone
Andy
theLizardPosted Sep 7, 2010, 8:25 PM
I have tested what you have said with the following code (not all were used at the same time)
private void button1_Click(object sender, EventArgs e) //this works, creates the file
{
f = new FileInfo("hello.txt");
StreamWriter sw = new StreamWriter(@"yoyr path\hello.txt", true);
sw.WriteLine("Hello Fred");
sw.Flush();
}
private void frmMain_FormClosed(object sender, FormClosedEventArgs e) //this works
{
f = new FileInfo("hello.txt");
f.Delete();
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e) // and this works
{
f.Delete();
}
However your error is coming from this.
You are creating a stream reader
StreamReader reader = new StreamReader(System.Environment.CurrentDirectory + "\\Email.txt");
But you are NOT closing it and therefore you are getting "The process cannot access the file [file name] because it is being used by another process which of course is correct.
Try doing reader.Close(); before deleting the file
Dipal ChoksiPosted Sep 7, 2010, 2:57 PM
Sam HobbsPosted Sep 7, 2010, 2:43 PM
Also note that in the line:
System.IO.FileInfo fidel = new FileInfo("email.txt");
You have "System.IO" in the left part but not in the right side. So you might be getting an error only because you don't specify System.IO in the right side also. I don't know if that is the problem; it is only a guess. It would really help so very much to know what the error is that you are getting.
Also note that it is easieer for you to add the event handler using the form's properties but people that help in forums such as this often don't describe that option since it is more work to type in a description. Do you know how to add events to forms and controls using their properties?
Tanmay SarkarPosted Sep 7, 2010, 12:51 PM
you paste it in
public Form1()
{
InitializeComponent();
Form1.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
}
for best you put this code in Form1.Designer.cs
in
private void InitializeComponent()
{
.......
}
& write the handler in Form1.cs
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
..................
}
when u writing a message will show to press tab ,& if you press it, automatically code will generate.
Thank you!
If it help you then mark it as an answer.
Posted Sep 7, 2010, 9:30 AM
I'm having no luck finding where to put it myself & I'm tipping most people reading this are having the same problem as I haven't put in the associated code.
So here's the code for my Form1, you'll see where I last tried it (commented out as it doesn't work):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Threading;
namespace MyMessengerGUI
{
public partial class Form1 : Form
{
SerialPort sp = new SerialPort();
string input = "";
public Form1()
{
InitializeComponent();
}
//
//
//Code in here to send message out
//
private void Form1_Load(object sender, EventArgs e)
{
lblStatus.Text = "";
cmbRecipient.DropDownStyle = ComboBoxStyle.DropDownList;
cmbBoxPorts.DropDownStyle = ComboBoxStyle.DropDownList;
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
cmbBoxPorts.Items.Add(port);
}
try
{
cmbBoxPorts.SelectedIndex = 0;
}
catch { }
try
{
DataTable table = new DataTable();
DataColumn colPhoneNum = new DataColumn("Email");
DataColumn colDevice = new DataColumn("Recipient");
table.Columns.Add(colEmail);
table.Columns.Add(colRecipient);
StreamReader reader = new StreamReader(System.Environment.CurrentDirectory + "\\Email.txt");
do
{
table.Rows.Add(reader.ReadLine().Split(','));
}
while (reader.Peek() != -1);
cmbRecipient.DataSource = table;
cmbRecipient.DisplayMember = "Email";
cmbRecipient.ValueMember = "Recipient";
cmbRecipient.SelectedIndex = 0;
}
catch
{
MessageBox.Show("ERROR: Unable to read txt file.\r\nCreate a 'Email.txt' file in the following format...\r\n\r\n,Please Select Recipient\r\[email protected],Andy R\r\[email protected],Brian N");
}
Form1.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
System.IO.FileInfo fidel = new FileInfo("Email.txt");
fidel.Delete();
}
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
MessageBox.Show("Version 1.0\r\nE-mailer.");
}
}
}
As always, your help is GREATLY appreciated.
Andy
Posted Sep 7, 2010, 8:32 AM
I've tried putting the following code in a few places, but it keeps throwing up errors at debug:
Form1.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
System.IO.FileInfo fidel = new FileInfo("email.txt");
fidel.Delete();
}
I've put it in Form1.cs and in Program.cs but it always ends up with an error.
I'm really not sure where it's meant to go, I guess you'd have difficulty as you don't know where it resides in my code.
What I can tell you is that I start at the bottom of each *.cs and keep working up to the next } and try it again.
Sorry for the confusion, I hope you can understand what I'm trying to say.
Kind regards, and thanks again
Andy
Mamta MPosted Sep 7, 2010, 8:20 AM
YourFormName.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.YourFormName_FormClosing);
private void YourFormName_FormClosing(object sender, FormClosingEventArgs e)
{
. . .
fidel.Delete();
}
Posted Sep 7, 2010, 8:08 AM
thanks for your super-quick reply.
I must apologise, I'm a complete beginner at programming, so I don't really know what I'm doing.
My form code doesn't have a specified closing event, as I was under the impression that the windows standard form close button took care of everything like that.
If it's not too much trouble, would you be kind enough to give me some code to put at the end of my Form1.cs code to make this work as you suggest?
Thanks again in advance.
Andy
Mamta MPosted Sep 7, 2010, 7:27 AM