Невозможно удалить файл PDF после отправки письма
Мой код обрабатывает информацию на веб-сайте, затем экспортирует ее в текстовые документы, затем преобразует ее в PDF и продолжает прикреплять ее к коду электронной почты. Мне удалось отправить электронное письмо с PDF, но у меня проблемы с управлением файлами. В этом случае я хотел бы удалить файлы в папке, а именно, сгенерированное слово и PDF-документ. Код работает и был в состоянии удалить документ word, но не смог удалить документ PDF.
Ошибка, когда я вручную пытался удалить файл, был "Действие не может быть завершено, потому что файл открыт в webdev.webserver40.exe". В настоящее время работает в режиме отладки, и в будущем вы захотите запустить его на IIS.
Ниже приведен фрагмент моего кода электронной почты
Dim Smtp_Server As New SmtpClient
Dim e_mail As New MailMessage()
Smtp_Server.UseDefaultCredentials = False
e_mail = New MailMessage()
e_mail.Subject = "Job Completed "
e_mail.IsBodyHtml = False
e_mail.Body = msg
e_mail.Attachments.Add(New Attachment(Server.MapPath("PDF\" + filename + ".pdf")))
Smtp_Server.Send(e_mail)
Smtp_Server.Dispose()
e_mail.Attachments.Clear()
e_mail.Dispose()
Удалена аутентификация и адрес отправки. Ниже приведен код для удаления файлов
Dim filePaths As String() = Directory.GetFiles(HttpContext.Current.Server.MapPath("PDF"))
For Each filePath As String In filePaths
File.Delete(filePath)
Next
ниже находится файл класса, который используется для преобразования PDF
Imports Microsoft.VisualBasic
Imports System.IO
Imports Microsoft.Office.Interop.Word
Public Class ConvertWordToPDF
Public Sub convertToPDF(strFileName As String)
' Create a new Microsoft Word application object
Dim word As New Microsoft.Office.Interop.Word.Application()
' C# doesn't have optional arguments so we'll need a dummy value
Dim oMissing As Object = System.Reflection.Missing.Value
' Get list of Word files in specified directory
Dim dirInfo As New DirectoryInfo(HttpContext.Current.Server.MapPath("PDF"))
Dim wordFiles As FileInfo() = dirInfo.GetFiles("*.docx")
word.Visible = False
word.ScreenUpdating = False
' Cast as Object for word Open method
Dim filename As [Object] = DirectCast(wordFiles(0).FullName, [Object])
'Dim fileName As Object = strFileName
' Use the dummy value as a placeholder for optional arguments
Dim doc As Document = word.Documents.Open(fileName, oMissing, oMissing, oMissing, oMissing, oMissing, _
oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, _
oMissing, oMissing, oMissing, oMissing)
doc.Activate()
Dim outputFileName As Object = wordFiles(0).FullName.Replace(".docx", ".pdf")
Dim fileFormat As Object = WdSaveFormat.wdFormatPDF
' Save document into PDF Format
doc.SaveAs(outputFileName, fileFormat, oMissing, oMissing, oMissing, oMissing, _
oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, _
oMissing, oMissing, oMissing, oMissing)
' Close the Word document, but leave the Word application open.
' doc has to be cast to type _Document so that it will find the
' correct Close method.
Dim saveChanges As Object = WdSaveOptions.wdDoNotSaveChanges
DirectCast(doc, _Document).Close(saveChanges, oMissing, oMissing)
doc = Nothing
' word has to be cast to type _Application so that it will find
' the correct Quit method.
DirectCast(word, _Application).Quit(oMissing, oMissing, oMissing)
word = Nothing
End Sub
End Class
Изменить: Добавлен код, чтобы проверить, заблокирован ли файл
Protected Overridable Function IsFileLocked(file As FileInfo) As Boolean
Dim stream As FileStream = Nothing
Try
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)
Catch generatedExceptionName As IOException
'the file is unavailable because it is:
'still being written to
'or being processed by another thread
'or does not exist (has already been processed)
Return True
Finally
If stream IsNot Nothing Then
stream.Close()
End If
End Try
'file is not locked
Return False
End Function
он вернул false после того, как PDF был создан.
1 ответ
Только что проверил сценарий, где я смог воспроизвести проблему. Я смог исправить это, добавив вложение в виде потока, а не просто путь к файлу. Просто не забудьте закрыть поток так или иначе.
Этот код выдает ошибку, которую вы описали:
Dim smtp As New SmtpClient("...")
message.Attachments.Add(New Attachment("c:\myfile.txt"))
smtp.Send(message)
File.Delete("c:\myfile.txt")
Это работает:
Dim smtp As New SmtpClient("...")
Using reader As New StreamReader("C:\myfile.txt")
Dim a As New Attachment(reader.BaseStream, "myfile.txt")
message.Attachments.Add(a)
smtp.Send(message)
End Using
File.Delete("c:\myfile.txt")