• 0

File Access Question (C#)


Question

Hello everyone.

I have an application that zips up some files and then attempts to send that in an e-mail as an attachment.

I have noticed that if the zip file is small it works fine (A few KB's), but the zip is generally between 1 and 2 MB's, and at that size (Which is still rather small) it fails. I get an error that it failed due to the target of an invocation.

I'm assuming that perhaps the zip file is not being released prior to the e-mail being generated when it's larger? I have both the zip creation and e-mail generation in their own backGroundWorkers.

I've been working on this for a good while now, and it doesn't seem to matter if my AntiVirus is running (I thought maybe it was trying to scan the zip), if I do a thread.Sleep, if I choose to send the mail upon the click of another button, etc. In fact, curiously, I created a test application that ONLY sends the zip file. This works perfectly. However, if I use my main application to create the zip file, this test application will be unable to send the zip until after the main application is closed. I really think that the file is not being released, but I don't know why, or from what. The backgroundWorker that is creating the zip is completing successfully (That is where I was originally calling the SendMail event).

My question is what the suggested course of action would be for doing something like this. I've never had an issue with accessing a file like this before.

I really appreciate any suggestions anyone may have for this. I can post whatever code you want, but there's a lot of it, so I'm not sure what all you would want.

Thanks Again,

Link to comment
https://www.neowin.net/forum/topic/846100-file-access-question-c/
Share on other sites

11 answers to this question

Recommended Posts

  • 0

My first train of thought would be to remove it from the backgroundworker and just run the whole thing in a single thread, see if that makes a difference. I would say its worth having a look at your code too and making sure that you're releasing any file handles that you're creating in the process.

Might be worth posting some relevant code (if you can) so we can take a look.

  • 0
what is you're code for creating the zip file?

i like to use the ShapZipLib .NET Zip Library personally, have you given that a go?

can't really do much without knowing what your code is up to so, i await the response :)

Thank you very much for your response. I haven't tried that. I've been using DotNetZip Library (http://dotnetzip.codeplex.com/). It's been really good, and after mentioning this to the developer, it doesn't appear to be related to any of DotNetZip's code...

Here is the code for creating the zip:

		void CompileZip()
		{
			try
			string tempFolder = Path.GetTempPath();
			if (File.Exists(tempFolder + @"\JobFile.zip"))
			{
					SendMail()
			 }
			 else
			 {
					string[] tempDirectory = { tempFolder };
					CompileZipbackgroundWorker2.RunWorkerAsync(tempDirectory);
					Application.DoEvents();
			 }
		}

		private void CompileZipbackgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
		{
			BackgroundWorker worker = sender as BackgroundWorker;
			string[] tempDirectory = (string[])e.Argument;
			string FilePath = tempDirectory[0].ToString();

			string current = Directory.GetCurrentDirectory();
			System.IO.Directory.SetCurrentDirectory(FilePath);

			//int progress = 10;

			using (ZipFile zip = new ZipFile())
			{
				//Add Generated Files to zip
				zip.AddItem("JobFile");
				zip.AddItem("Resources");

				worker.ReportProgress(20);
				worker.ReportProgress(90);

				//Save the zip
				zip.Save(Path.Combine(FilePath, "JobFile.zip"));
			}
			Application.DoEvents();
			worker.ReportProgress(100);
			System.IO.Directory.SetCurrentDirectory(current);
		}

		private void CompileZipbackgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			SubProgressBar1.Value = e.ProgressPercentage;
		}

		private void CompileZipbackgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			if ((e.Cancelled == true))
			{
				MessageBox.Show("Canceled", "Error", MessageBoxButtons.OK);
			}

			else if (!(e.Error == null))
			{
				MessageBox.Show(e.Error.Message, "Error", MessageBoxButtons.OK);
			}

			else
			{
				string tempFolder = Path.GetTempPath();
				string zipedFile = tempFolder + @"\JobFile.zip";
				if (File.Exists(zipedFile))
				{
					try
					{
						SubProgressBar1.Style = ProgressBarStyle.Continuous;

						SendMail();
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Error.Message, "Error", MessageBoxButtons.OK);

						return;
					}
				}
			}
		}

Here's the code for sending the E-Mail:

		void SendMail()
		{
			try
			{
				SubProgressBar1.Style = ProgressBarStyle.Marquee;

				string ccState = "";
				if (CCCheckBox1.Checked == true)
				{
					ccState = "true";
				}
				else
				{
					ccState = "false";
				}

				string urgentState = null;
				if (UrgentCheckBox1.Checked == true)
				{
					urgentState = "true";
				}
				else
				{
					urgentState = "false";
				}

				string attachState = null;
				if (SubmitStepTB1.Text == "Attach")
				{
					attachState = "true";
				}
				else
				{
					attachState = "false";
				}

				string[] SendMail = { CustLastNameTB1.Text, CustFirstNameTB1.Text, UserCB1.Text, UserEMailTB1.Text, AssemblyVersion, JobFileNotesTB1.Text, ccState, urgentState, attachState };
				SendMailbackgroundWorker1.RunWorkerAsync(SendMail);
			}
			catch
			{

			}
		}

		private void SendMailbackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
		{
			try
			{
				string[] SendMail = (string[])e.Argument;
				string CustLastName = SendMail[0].ToString();
				string CustFirstName = SendMail[1].ToString();
				string User = SendMail[2].ToString();
				string UserEMail = SendMail[3].ToString();
				string SoftVersion = SendMail[4].ToString();
				string JobFileNotes = SendMail[5].ToString();
				string CCState = SendMail[6].ToString();
				string UrgentState = SendMail[7].ToString();
				string attachState = SendMail[8].ToString();

				//Send E-Mail on click of Button
				MailMessage theMailMessage = new MailMessage("FromEMail", "ToEMail");

				BackgroundWorker worker = sender as BackgroundWorker;
				//worker.ReportProgress(25);

				//Generate the message body
				string messageBody = "New Job File Information Added For:  " + CustLastName + ", " + CustFirstName;
				messageBody += Environment.NewLine + "";
				messageBody += Environment.NewLine + "From:  " + User;
				messageBody += Environment.NewLine + "E-Mail:  " + UserEMail + "  (CC'd =  " + CCState + ")";
				messageBody += Environment.NewLine + "";
				messageBody += Environment.NewLine + "Software Version:  " + SoftVersion;
				messageBody += Environment.NewLine + "";
				messageBody += Environment.NewLine + @"\\server\shared\job files\" + CustLastName + ", " + CustFirstName + @"\";
				messageBody += Environment.NewLine + "";
				messageBody += Environment.NewLine + "Notes:  " + JobFileNotes;

				//worker.ReportProgress(50);

				//Set the property of the message body and subject body
				theMailMessage.Body = messageBody;
				theMailMessage.Subject = "New Job File for " + CustLastName + ", " + CustFirstName;

				//Set the CC Property
				if (CCState == "true")
				{
					MailAddress copy = new MailAddress(UserEMail);
					theMailMessage.CC.Add(copy);
				}

				//Set the Urgent Property
				if (UrgentState == "true")
				{
					theMailMessage.Priority = MailPriority.High;
				}

				//Set the Attachment Property
				if (attachState == "true")
				{
					string tempFolder = Path.GetTempPath();
					theMailMessage.Attachments.Add(new Attachment(tempFolder + @"\JobFile.zip"));
				}

				//worker.ReportProgress(75);

				//E-Mail Credentials and Sending
				SmtpClient theClient = new SmtpClient("smtp.1and1.com");
				System.Net.NetworkCredential theCredential = new
				System.Net.NetworkCredential("FromEMail", "Password");
				theClient.Credentials = theCredential;
				theClient.Send(theMailMessage);

				//worker.ReportProgress(100);
			}
			catch
			{
				MessageBox.Show("The Mail Message was unable to be sent.", "Error", MessageBoxButtons.OK);
			}
		}

		private void SendMailbackgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			SubProgressBar1.Value = e.ProgressPercentage;
		}

		private void SendMailbackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			SubProgressBar1.Increment(100);

			Application.DoEvents();
		}

That should be everything. I'm curious what your thoughts might be. The SendMail code does work (As evidenced by the test project I created), but not if the file has just been created.

Thanks Again. If there is anything else you might want to look at, please let me know. I really, REALLY appreciate the help. I'm just completely out of ideas here and it's driving me nuts...

Edited by M_Lyons10
  • 0

Thank you very much for the suggestion. I will try that to see if it is able to send the mail, but the reason I had initially used a backgroundWorker was because the UI was locking up. Additionally, as the zip process takes some time, the code was attempting to send the mail prior to the zip being completed.

Thanks Again,

  • 0
yeah i understand why the background process is there, but i think for the purposes of working out whats wrong it should be chopped.

it might also be related to having one end background process call another background process.. but i'm unsure

Thanks for your help and everything. I did rewrite the code yesterday / last night and was testing it. It locks up the UI something fierce, but it does work. So, the backgroundWorker is not terminating? Or is somehow holding onto the file? I thought that when a backgroundWorker completed it was done / terminated. I'm not sure what the difference would possibly be. I had run the application a bit ago while watching the file access of the zip file using Process Monitor and it was closing...

You say it's the "sendmail" that's failing. Many ISPs restrict the size of e-mails, so it's possible it's being rejected by the server because the payload is too large.

I realize that some do restrict attachment size, but I've never seen such a small limit (1 - 2 MB's). Just to test that though, I did make a test application that sends the zip file that has already been compiled. It works perfectly so long as the application that created the zip has exited.

Thanks Again,

  • 0

first thing first ... if you get an exception and you are working with backgroundworkers, check the InnerException property - it should encapsulate what exception was raised in the background worker.

Secondly, since you have your send mail worker code wrapped up nicely in a try...catch clause, your assumption that the file is not release properly is void (+ the fact that you are using "using" clause when building the zip file helps in that it will release any stuff used by ZipFile immediatly (if coded properly by the DotNetZip dev))

I "tried" to replicate as close as possible the requirements of the code you posted (basically a progress bar, a button and a few checkboxes) to try to replicate the issue, and from what I can tell, you are trying to Increment the progress bar value when it is in Marquee Mode.

Hinty: Its a good idea to use BackgroundWorker for these kind of situations - situations that involve a UI and length operations so stick to it :) Just when you are handling exceptions, try not to use catch-all exception handlers so that if there is some serious "unhandled" stuff going on in your worker, an exception will be raised, and that can help you out to find the cause and fix it.

  • 0
first thing first ... if you get an exception and you are working with backgroundworkers, check the InnerException property - it should encapsulate what exception was raised in the background worker.

Secondly, since you have your send mail worker code wrapped up nicely in a try...catch clause, your assumption that the file is not release properly is void (+ the fact that you are using "using" clause when building the zip file helps in that it will release any stuff used by ZipFile immediatly (if coded properly by the DotNetZip dev))

I "tried" to replicate as close as possible the requirements of the code you posted (basically a progress bar, a button and a few checkboxes) to try to replicate the issue, and from what I can tell, you are trying to Increment the progress bar value when it is in Marquee Mode.

Hinty: Its a good idea to use BackgroundWorker for these kind of situations - situations that involve a UI and length operations so stick to it :) Just when you are handling exceptions, try not to use catch-all exception handlers so that if there is some serious "unhandled" stuff going on in your worker, an exception will be raised, and that can help you out to find the cause and fix it.

Thank you very much for your response. I will take a look at the InnerException property. I will look into the progressBar increment as well. That may have been an error on my part. The error being thrown the Visual Studio is that the mail message timed out. I will try to improve the catches to help a bit further. It's an odd error and I am not sure what the solution would really be. Programs perform processes like this all the time, but it's really giving me a headache.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • When will the Photos app be updated to remember the window size and position when reopened? They addressed this issue in a 2024 version of the app (though I can't recall the build number). Unfortunately, after that specific version, the problem persists! Please prioritise this fix in your K2 schedule. Additionally, the Snipping Tool has lost the ability to capture the Windows Taskbar starting from the 2024 version!
    • Same, never saw it on Android or iOS. Guess only some people got it *shrugs*
    • Anthropic pulls Fable 5 and Mythos 5 after US export control order by Pradeep Viswanathan In April this year, Anthropic launched the Claude Mythos Preview frontier model with state-of-the-art cyber and coding capabilities for a select set of companies around the world. After preparing appropriate guardrails, early this week, Anthropic launched Claude Fable 5 and Mythos 5, its most capable AI models. Claude Fable 5 is for general users and comes with strict safeguards, while Mythos 5 is designed with fewer safeguards for cybersecurity and biology use cases. Today, Anthropic abruptly suspended access to its Fable 5 and Mythos 5 AI models for all customers after receiving an export control directive from the US government. The company received the directive from the government today at 5:21 p.m. ET, and the received letter did not provide any details regarding the national security concern. Anthropic understands that the government became aware of a method to bypass, or “jailbreak,” Fable 5, which might be the reason behind the directive. The order was issued under national security authorities and requires the company to suspend all access to Fable 5 and Mythos 5 by any foreign national, whether they are inside or outside the United States. The restriction also applies to foreign national employees working at Anthropic. As a result, the company has disabled both models for all customers to ensure compliance. Access to previous Anthropic models like Opus and Sonnet is not affected by this government order. The company highlighted that it had developed strong safeguards to reduce the possibility that Fable is misused for tasks related to cybersecurity. In fact, many developers are complaining that the safeguards are going overboard. Additionally, the company worked with the US government, the UK AISI, multiple private third-party organizations, and internal teams to red-team Fable’s safeguards for thousands of hours. Finally, Anthropic noted that no testers have yet been able to find a universal jailbreak on Fable 5. As expected, Anthropic disagrees that a narrow potential jailbreak should lead to the recall of a commercial model used by hundreds of millions of people. It warned that applying this standard across the AI industry could effectively halt new frontier model deployments. Anthropic concluded by mentioning that it is working to restore access to Fable 5 and Mythos 5 as soon as possible and plans to share more details within the next 24 hours.
    • Brave Browser 1.91.172 is out.
  • Recent Achievements

    • Week One Done
      ssd21345 earned a badge
      Week One Done
    • Contributor
      MarkHughes4096 went up a rank
      Contributor
    • Dedicated
      jordanspringer earned a badge
      Dedicated
    • Rookie
      Rimplesnort went up a rank
      Rookie
    • One Year In
      Markus94287 earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      503
    2. 2
      +Edouard
      176
    3. 3
      PsYcHoKiLLa
      147
    4. 4
      ATLien_0
      92
    5. 5
      Steven P.
      79
  • Tell a friend

    Love Neowin? Tell a friend!