Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除文件失败,因为由和现有进程保留_C#_Email_Delete File - Fatal编程技术网

C# 删除文件失败,因为由和现有进程保留

C# 删除文件失败,因为由和现有进程保留,c#,email,delete-file,C#,Email,Delete File,我在用C#编写的代码中遇到了一些问题 我正在使用MailMessage和SMTP组件发送文档。我将要发送的文件复制到临时目录(如c:\temp),循环浏览文档并将其附加到电子邮件中 电子邮件发送正常,但当我尝试从临时目录中删除文件时,出现以下错误: 进程无法访问该文件,因为其他进程正在使用该文件 我不明白为什么会这样。下面是处理文档的代码 public void sendDocument(String email, string barcode, int requestid) {

我在用C#编写的代码中遇到了一些问题

我正在使用MailMessage和SMTP组件发送文档。我将要发送的文件复制到临时目录(如c:\temp),循环浏览文档并将其附加到电子邮件中

电子邮件发送正常,但当我尝试从临时目录中删除文件时,出现以下错误:

进程无法访问该文件,因为其他进程正在使用该文件

我不明白为什么会这样。下面是处理文档的代码

public void sendDocument(String email, string barcode, int requestid)
    {

        string tempDir = @"c:\temp";

        //first we get the document information from the database.
        Database db = new Database(dbServer, dbName, dbUser, dbPwd);

        List<Document> documents = db.getDocumentByID(barcode);
        int count = 0;
        foreach (Document doc in documents)
        {
            string tempPath = tempDir + "\\" + doc.getBarcode() + ".pdf";
            string sourcePath = doc.getMachineName() + "\\" + doc.getFilePath() + "\\" + doc.getFileName();

            //we now copy the file from the source location to the new target location
            try
            {
                //this copies the file to the folder
                File.Copy(sourcePath, tempPath, false);

            }
            catch (IOException ioe)
            {
                count++; 

                //the file has failed to copy so we add a number to the file to make it unique and try
                //to copy it again.
                tempPath = tempDir + "\\" + doc.getBarcode() + "-" + count + ".pdf";
                File.Copy(sourcePath, tempPath, false);

            }

            //we now need to update the filename in the to match the new location
            doc.setFileName(doc.getBarcode() + ".pdf");                

        }

        //we now email the document to the user.
        this.sendEmail(documents, email, null);

        updateSentDocuments(documents, email);

        //now we update the request table/
        db.updateRequestTable(requestid);


        //now we clean up the documents from the temp folder.
        foreach (Document doc in documents)
        {
            string path = @"c:\temp\" + doc.getFileName();
            File.Delete(path);
        }

    }
public void sendDocument(字符串电子邮件、字符串条形码、int requestid)
{
字符串tempDir=@“c:\temp”;
//首先,我们从数据库中获取文档信息。
Database db=新数据库(dbServer、dbName、dbUser、dbPwd);
列表文档=db.getDocumentByID(条形码);
整数计数=0;
foreach(文档中的文档)
{
字符串tempPath=tempDir+“\\”+doc.getBarcode()+“.pdf”;
字符串sourcePath=doc.getMachineName()+“\\”+doc.getFilePath()+“\\”+doc.getFileName();
//现在,我们将文件从源位置复制到新的目标位置
尝试
{
//这会将文件复制到文件夹中
Copy(sourcePath、tempPath、false);
}
捕获(ioe异常ioe)
{
计数++;
//该文件复制失败,因此我们向该文件添加一个数字以使其唯一,然后重试
//再复制一次。
tempPath=tempDir+“\\”+doc.getBarcode()+“-”+count+“.pdf”;
Copy(sourcePath、tempPath、false);
}
//我们现在需要更新中的文件名以匹配新位置
doc.setFileName(doc.getBarcode()+“.pdf”);
}
//我们现在通过电子邮件将文档发送给用户。
此.sendmail(文档、电子邮件、空);
更新新文档(文档、电子邮件);
//现在我们更新请求表/
db.updateRequestTable(requestid);
//现在,我们清理临时文件夹中的文档。
foreach(文档中的文档)
{
字符串路径=@“c:\temp\”+doc.getFileName();
删除(路径);
}
}
我认为this.sendmail()方法在返回sendDocument方法之前会发送电子邮件,因为我认为是smtp对象导致删除失败

这是sendEmail方法:

public void sendEmail(List<Document> documents, String email, string division)
    {
        String SMTPServer = null;
        String SMTPUser = null;
        String SMTPPwd = null;
        String sender = "";
        String emailMessage = "";

        //first we get all the app setting used to send the email to the users
        Database db = new Database(dbServer, dbName, dbUser, dbPwd);

        SMTPServer = db.getAppSetting("smtp_server");
        SMTPUser = db.getAppSetting("smtp_user");
        SMTPPwd = db.getAppSetting("smtp_password");
        sender = db.getAppSetting("sender");
        emailMessage = db.getAppSetting("bulkmail_message");

        DateTime date = DateTime.Now;

        MailMessage emailMsg = new MailMessage();

        emailMsg.To.Add(email);

        if (division == null)
        {
            emailMsg.Subject = "Document(s) Request - " + date.ToString("dd-MM-yyyy");
        }
        else
        {
            emailMsg.Subject = division + " Document Request - " + date.ToString("dd-MM-yyyy");
        }

        emailMsg.From = new MailAddress(sender);
        emailMsg.Body = emailMessage;

        bool hasAttachements = false;

        foreach (Document doc in documents)
        {

            String filepath = @"c:\temp\" + doc.getFileName();

            Attachment data = new Attachment(filepath);
            emailMsg.Attachments.Add(data);

            hasAttachements = true;


        }

        SmtpClient smtp = new SmtpClient(SMTPServer);

        //we try and send the email and throw an exception if it all goes tits.
        try
        {
            if (hasAttachements)
            {
                smtp.Send(emailMsg);
            }
        }
        catch (Exception ex)
        {
            throw new Exception("EmailFailure");
        }


    }
public void sendmail(列出文档、字符串电子邮件、字符串划分)
{
字符串SMTPServer=null;
字符串SMTPUser=null;
字符串SMTPPwd=null;
字符串发送者=”;
字符串emailMessage=“”;
//首先,我们获得了用于向用户发送电子邮件的所有应用程序设置
Database db=新数据库(dbServer、dbName、dbUser、dbPwd);
SMTPServer=db.getAppSetting(“smtp_服务器”);
SMTPUser=db.getAppSetting(“smtp_用户”);
SMTPPwd=db.getAppSetting(“smtp_密码”);
sender=db.getAppSetting(“sender”);
emailMessage=db.getAppSetting(“bulkmail_message”);
DateTime date=DateTime.Now;
MailMessage emailMsg=新邮件();
emailMsg.To.Add(电子邮件);
if(除法==null)
{
emailMsg.Subject=“文件请求-”+日期.ToString(“dd-MM-yyyy”);
}
其他的
{
emailMsg.Subject=division+“文档请求-”+date.ToString(“dd-MM-yyyy”);
}
emailMsg.From=新邮件地址(发件人);
emailMsg.Body=emailMessage;
bool hasAttachements=false;
foreach(文档中的文档)
{
字符串filepath=@“c:\temp\”+doc.getFileName();
附件数据=新附件(文件路径);
emailMsg.Attachments.Add(数据);
hasAttachements=true;
}
SmtpClient smtp=新SmtpClient(SMTPServer);
//我们尝试发送电子邮件,如果一切顺利,就会抛出异常。
尝试
{
if(附件)
{
smtp.Send(emailMsg);
}
}
捕获(例外情况除外)
{
抛出新异常(“EmailFailure”);
}
}
如何通过占用我希望删除的文件的进程来解决这个问题


一旦应用程序完成,我可以删除这些文件。

第一步是找出问题文件的处理过程。我将获取SysInternals工具包,并使用handle.exe命令确定文件中包含的进程

如果不知道文件打开的是哪个进程,就无法解决此问题


Sysinternals链接:

您的电子邮件未被处理,请在发送后尝试处理它:

 try
 {
      if (hasAttachements)
      {
          smtp.Send(emailMsg);         
      }
 }  
 catch ...
 finally
 {
      emailMsg.Dispose();
 }

这是我刚刚发现的一个技巧,希望对其他人有用? 在向邮件添加附件之前,请在using包装器中创建附件。这样可以确保正确处置该文件,从而成功删除该文件。我不确定发送是否也需要在这个循环中;(当我测试时,起初电子邮件没有通过,半小时后我被淹没,所以决定在网络稍微平静一点的时候离开测试)

反正对我来说没问题:)

祝你好运

JB

using (Attachment attachment = new Attachment(filename))
{
    message.Attachments.Add(attachment);
    client.SendAsync(message, string.Empty);
}
File.Delete(filename);