• 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

    • That's just silly imo. The lengths that man goes to just to avoid W11 is just nuts. Very, very few home users would do that. I will say this though, he is committed. Btw, I note on askwoody that Woody Leonhard passed away March, 2025 aged 73. His site was one of my favorites back in the day. Belated yes but RIP Woody.
    • Because of the EU (a good thing) newer android devices been getting 5 years worth of security patches. Except some Motorola which found the loop hole, and offer ZERO updates. In addition, Google for years have been making where it can patch some stuff by updating the core Google Play Store itself.  As echoed earlier,  you take the security risk in to your own hand beyond supported.
    • Win11Debloat 06.11.2026 by Razvan Serea Win11Debloat is a lightweight, easy to use PowerShell script that allows you to quickly declutter and customize your Windows experience. It can remove pre-installed bloatware apps, disable telemetry, remove intrusive interface elements and much more. The script also includes many features that system administrators and power users will enjoy. Such as a powerful command-line interface, support for Windows Audit mode and the option to make changes to other Windows users. All changes made by Win11Debloat can be easily reversed, and most removed apps can be restored via the Microsoft Store. A full guide on how to undo the changes is available here. Win11Debloat features: Below is an overview of the key features and functionality offered by Win11Debloat. Please refer to the wiki for more information about the default settings preset. Remove a wide variety of preinstalled apps. Click here for more info. Disable telemetry, diagnostic data, activity history, app-launch tracking & targeted ads. Disable tips, tricks, suggestions & ads across Windows. Disable Windows location services & app location access. Disable Find My Device location tracking. Disable 'Windows Spotlight' and tips & tricks on the lock screen. Disable 'Windows Spotlight' desktop background option. Disable ads, suggestions and the MSN news feed in Microsoft Edge. Hide Microsoft 365 ads on the Settings 'Home' page, or hide the 'Home' page entirely. Disable & remove Microsoft Copilot. Disable Windows Recall. Disable Click to Do, AI text & image analysis tool. Prevent AI service (WSAIFabricSvc) from starting automatically. Disable AI Features in Edge. Disable AI Features in Paint. Disable AI Features in Notepad. Disable the Drag Tray for sharing & moving files. Restore the old Windows 10 style context menu. Turn off Enhance Pointer Precision, also known as mouse acceleration. Disable the Sticky Keys keyboard shortcut. Disable Storage Sense automatic disk cleanup. Disable fast start-up to ensure a full shutdown. ...and more. Once you’ve downloaded the Win11Debloat file (Get.ps1), just follow these quick steps: Locate the Get.ps1 script file. Right-click the file and select Run with PowerShell from the context menu. If prompted by User Account Control (UAC), select Yes to grant the script the necessary administrative permissions. Win11Debloat 06.11.2026 fixes: Fix lock screen spotlight option being disabled when disabling the start recommended section by @Raphire in #619 Fix log message formatting by @Raphire Note The -RemoveCommApps and -RemoveW11Outlook command-line parameters for uninstalling a few specific apps have been removed with this release. If you previously relied on these parameters, please see this wiki page for alternative methods of removing these apps. Download: Win11Debloat 06.11.2026 | Open Source View: Win11Debloat Home Page | Screenshots 1| 2 Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • Rookie
      restore went up a rank
      Rookie
    • Very Popular
      AndrewSteel earned a badge
      Very Popular
    • Veteran
      Taliseian went up a rank
      Veteran
    • One Month Later
      Clizby earned a badge
      One Month Later
    • One Month Later
      Timaximus earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      502
    2. 2
      +Edouard
      162
    3. 3
      PsYcHoKiLLa
      154
    4. 4
      ATLien_0
      83
    5. 5
      Steven P.
      79
  • Tell a friend

    Love Neowin? Tell a friend!