1

I have a small email-program which does encryption. Below is just a summary of the program:

private void sendEmailButton_Click(object sender, EventArgs e)
{
    else
    {    
        //////////////////////////////////////////////////////////////////////////
        if (encryptEverythingCheckBox.Checked)
        {
            encryptAll();
        }
        //////////////////////////////////////////////////////////////////////////

        // Email credentials network codes blahblah
        // Assign the sender's email address to MailAddress function
        MailAddress mailAddress = new MailAddress(username);
        // Tells the recipent the sender's email
        mailMessage.From = mailAddress;
        // Username & Password of your email address
        System.Net.NetworkCredential networkCredential;
        networkCredential = new System.Net.NetworkCredential(username, password);
        // Enable SSL to encypt the connection
        smtpClient.EnableSsl = true;
        // Disable the use of default credentials
        smtpClient.UseDefaultCredentials = false;
        // Specify your own credential
        smtpClient.Credentials = networkCredential;
        //port number and send email blahblahblah
        deleteEncryptedFile();
    }
}

So the problem I'm having now is regarding the void method of deleteEncryptedFile() and encryptAll(). Below are the codes:

public void deleteEncryptedFile()
{
    if (File.Exists(@"C:\EncryptedFile.pgp"))            
        File.Delete(@"C:\EncryptedFile.pgp");            
}

public void encryptAll()
{
    OpenFileDialog openFileDialog1 = new OpenFileDialog();
    openFileDialog1.InitialDirectory = "c:\\";
    openFileDialog1.RestoreDirectory = true;
    openFileDialog1.Title = "CHOOSE RECIPENT'S PUBLIC KEY";

    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        invisibleTextBox.Text = openFileDialog1.FileName.ToString();
        string encryptedbodymessage = pgp.EncryptString(messageRichTextBox.Text, new FileInfo(@invisibleTextBox.Text));
        messageRichTextBox.Text = "";
        messageRichTextBox.Text = encryptedbodymessage;

        if (attachmentTextBox.Text != "")
        {
            bool asciiArmor = false;
            bool withIntegrityCheck = false;
            pgp.EncryptFile(@attachmentTextBox.Text, @invisibleTextBox.Text, @"C:\EncryptedFile.pgp", asciiArmor, withIntegrityCheck);
            invisibleTextBox.Text = "";
            mailAttachment = new Attachment(@"C:\EncryptedFile.pgp");
        }
    }
}

So when the send button is clicked and files are encrypted and sent, I want to remove it from my computer. So I run the method deleteEncryptedFile to remove the EncryptedFile.pgp from my computer. But i kept getting this message that is saying:

"The process cannot access the file 'C:\EncryptedFile.pgp' because it is being used by another process."

But the only "other process" that I can think of is the encryption method (encryptAll()). But shouldn't that had been done? Please advice how I can solve this problem?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user2930173
  • 69
  • 2
  • 2
  • 8
  • probably you are forgetting a close event, but can't read it from your code. – Sercan Ozdemir Nov 08 '13 at 09:15
  • 1
    It is not a good practice to place files in root folder. – Ofiris Nov 08 '13 at 09:15
  • 2
    My hunch says that either `pgp.EncryptFile` or `new Attachment` has an open file handle on your encrypted file. – Kabbalah Nov 08 '13 at 09:18
  • @Ofiris This is just a mini proj for my tutorials, so i simply need to show the encryption though. but i don't want to manually remove it every single time. – user2930173 Nov 08 '13 at 09:20
  • What is `pgp` and what exactly happens in your `EncryptFile()` method? Are you releasing all sources to used object? – Abbas Nov 08 '13 at 09:22
  • @CodeCaster How do i use the the .dispose method? i googled and it uses filestream.dispose or whatnot. how do i use on File. – user2930173 Nov 08 '13 at 09:29
  • @Abbas Basically it is a encrypted file. abc.txt > pgp algorithm > abc.pgp. in the EncryptFile method, i encrypted the email messagebody and attachment using a public crypto key. – user2930173 Nov 08 '13 at 09:31
  • 1
    call, mailMessage.Dispose(); – Kurubaran Nov 08 '13 at 09:32
  • @AccessDenied THANK YOU SO MUCH! SOLVED!!! *although it was mailAttachment.Dispose that i used.* Really need similar examples to learn. – user2930173 Nov 08 '13 at 09:40

2 Answers2

8

Try disposing mail attachment before the delete process.

mailAttachment.Dispose();
Rakhita
  • 4,493
  • 1
  • 16
  • 15
  • In the case where you are using message.Attachments.Add(new Attachment(filename)); then you would use message.Attachments.Dispose(); – KFP Jul 26 '16 at 17:59
-3

Before deleting the your encrypt file you can verify and then delete.Following function can help you to find whether file is being used by another process or not.

public static bool IsFileLocked(string fileName)
        {
            FileStream stream = null;
            try
            {
                stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException)
            {
                return true;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
            return false;
        }
MaheshMajeti
  • 187
  • 12
  • 2
    You're treating symptoms with this, not the cause. – CodeCaster Nov 08 '13 at 09:26
  • A little too advance for me. I know what it does basically but i dont know how to apply to my project. It is possible to just kill a the process and delete the file? – user2930173 Nov 08 '13 at 09:27
  • Did you tried deleting the file after some time.I think When you are calling the function The file still in use.Here i would like to know what is the exact cause – MaheshMajeti Nov 08 '13 at 09:30
  • @CodeCaster.I thought when we are dealing with this type of processes like (Mail,Printing)System tasks.It will take time.because of that reason i have mentioned above solution. – MaheshMajeti Nov 08 '13 at 09:33
  • @MaheshMajeti this is exactly what i am thinking too. But how do i delay calling my functions. After the button is click, it goes like step 1 - encrypt email body and attachment, step 2 - email network credentials, step 3 - email ports(587 or 995), step 4 - return windows form to default, step 5 - delete the encrypted file. – user2930173 Nov 08 '13 at 09:35
  • you can write a service to delete your files in the system(With help of timer event you can achieve this).And also another best advice is dont hard code names.append guid string to that.it will be a good practise. – MaheshMajeti Nov 08 '13 at 09:37
  • 1
    _"@CodeCaster.I thought when we are dealing with this type of processes like (Mail,Printing)System tasks.It will take time.because of that reason i have mentioned above solution."_ - no, time has nothing to do with it. You just have to dispose resources implementing `IDisposable`. The only time when this function _may_ come in handy is when you're trying to read files that are opened outside your application. – CodeCaster Nov 08 '13 at 09:55