Cannot delete pdf due to ""The process cannot access the file"

Skip Navigation LinksHome  /  Support  /  Forums  /  DynamicPDF CoreSuite for .NET (v6)  /  Cannot delete pdf due to ""The process cannot access the file"

DynamicPDF CoreSuite for .NET (v6) Forum


I have a Asp.Net MVC 2 application written in C#.

I have 2 pdf's that are used as templates. Each pdf has process whereby the template is copied to a new file with a random name, form fields on the pdf are given values, a resulting byte[] is retrieved via a call to the Draw() method on the MergeDocument object, and lastly, I attempt to delete the temporary pdf file now that I've gotten a byte[] to stream to the user.

I am using the same code in 2 spots. The deletion works in one of those spots. In the other it does not. I get a "The process cannot access the file" error.

The main difference in the two methods is that, for the one where I cannot delete the file, I am using reflection and iterating over all the fields on the form of a pdf with a loop akin to:

foreach (ceTe.DynamicPDF.Forms.FormField f in document.Form.Fields)
{
  //code that gets a form field value from my object
  //Set the form field's value
  document.Form.Fields[f.Name].Value = val;
}

Code used to Copy the template pdf to a random file:

   basePdf = new FileInfo(basePath);
   basePdf.CopyTo(phyPath, true);

Code used to attempt deletion:

 FileInfo fInfo = new FileInfo(phyPath);
            try
            {
                if (fInfo.Exists)
                    fInfo.Delete();
                   
            }
            catch (Exception e)
            {
                LogUtil.WriteException("CreatePdf", e);
            }

Is there a way to ensure that the MergeDocument object has closed the file/stream it's using internally?
Posted by a ceTe Software moderator
Hello,

Our product does not allow you to delete the file immediately after merging or appending.  The reason for this is because our product, in an effort to be as efficient as possible, only reads in the part of the merged or appended PDF that it needs and then uses the rest of it right at the time it draws out the new file.  So when you try to delete the file after drawing the PDF, the file you are trying to delete is still in use and there is no way to close the file stream used by the MergeDocument internally.

The work around for this is to open the file and read the contents of that file into a byte array using a FileStream and then close the FileStream and delete that file. Then you can create a PdfDocument out of that byte array and create a MergeDocument out of that PdfDocument. 

Here is the pseudo code:

   //Create a filestream out of your file
   FileStream fs = new FileStream(@"C:\temp\pdfs\input\HelloWorld.pdf", FileMode.Open );

   byte[] contents = new byte[ fs.Length ];
   //Get the contents of the filestream
   fs.Read( contents, 0, (int)fs.Length );
   //Close the filestream, releasing any resources
   fs.Close();

   PdfDocument pdf = new PdfDocument( contents );
   MergeDocument document = new MergeDocument( pdf );
   document.DrawToWeb( @"test.pdf" );
   // Code to delete the file

Thanks,
ceTe Software Support Team.
I am having this similar issue with the v6.x .NET 4.0 dll in use on WinForms.

Seems like the MergeDocument and PDFDocument classes do not release the file handles once they've loaded a file, or something related.

The error I'm having is trying to do something like load a document, append another document to it, and then save the document back to the original file.

This issue exists even in your supplied example (WinForm_Merger_MergePDFs_VB)

Place a reference to the same PDF twice or Two Different PDFs and then attempt to save the PDF to either the same PDF or to One of the Two Different PDFs and it will throw an error:

ceTe.DynamicPDF.Merger.PdfParsingException: There was end error while parsing the input PDF file. The PDF is likely corrupt or invalid. ---> System.IO.IOException: The process cannot access the file 'C:\Users\Me\Desktop\PDF\File.pdf' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at zz93.nt.c()
   at zz93.nt.a()
   at zz93.cm.a(hj A_0)
   --- End of inner exception stack trace ---
   at zz93.cm.a(hj A_0)
   at zz93.dq.a(DocumentWriter A_0)
   at zz93.i2.b(DocumentWriter A_0)
   at ceTe.DynamicPDF.Merger.AppendedPage.a(DocumentWriter A_0, Int32 A_1, Int32 A_2)
   at ceTe.DynamicPDF.Merger.AppendedPage.DrawEntries(DocumentWriter writer, Int32 pageNumber, Int32 sectionPageNumber)
   at ceTe.DynamicPDF.Page.a(DocumentWriter A_0, Int32 A_1, Int32 A_2, Int32 A_3)
   at zz93.oh.d(Int32 A_0)
   at zz93.oh.u()
   at ceTe.DynamicPDF.Document.Draw(Stream stream)
   at ceTe.DynamicPDF.Document.Draw(String filePath)
   at MergePDFs.Merge.button2_Click(Object sender, EventArgs e) in C:\Program Files (x86)\ceTe Software\DynamicPDF v6.0.4 for .NET\Examples\Visual Studio 2010\WinForm\WinForm_VB\Merger_MergePDFs_VB\Merge.vb:line 581
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


It writes a 0 byte file to the saved location, if you attempt to delete the file (system-side) it throws back the underlying error you'd get if you attempted to perform this operation again on the same 0 byte file:

The action can't be completed because the file is open in MergePDFs.exe


I kindof get where your answer is coming from, but this seems misleading and/or shouldn't open the file to write out if it is just going to effectively 0 write the file you were intending to append to...  Your workaround seems to "fix" the issue, but that answer is effectively saying, "Don't use our component to append documents to an existing document", at least to me.
Posted by a ceTe Software moderator
Hello,

The sample examples which we have provided are proof of concept and you will need to make the necessary changes to it according to your requirement. If you would like to save the merged PDF document with same name and file path then you will need to get the input PDF which you are merging in the form of byte array by reading the file using FileStream class.  You can find the sample code in the above post. This will work for you.

If you continue getting the error then please send over more details about your requirements and the sample code or application which you are using to our support team at: support@cete.com so that they can look into it further.

Thanks,
ceTe Software Support Team.
I had a similar issue. The code I used to merge several pdf's into one document is below. I'm doing this in an ASP.NET MVC 2 application so it's good to go for the web. It seems rather roundabout and may not be the best, but it works fine and I'm not seeing any performance issues.

MergeOptions mo = new MergeOptions();
mo.DocumentJavaScript = true;
MergeDocument document = new MergeDocument();                        

//begin loop over list of pdfPaths you want to merge
        PdfDocument pdf = new PdfDocument(pdfPath);
        MergeDocument m = new MergeDocument(pdf);
        pdf = new PdfDocument(m.Draw());
        document.Append(pdf,mo);
//end looping over list of pdfNames you want to merge        

document.InitialPage = 1;
byte[] doc = document.Draw();

//do whatever with doc

All times are US Eastern Standard time. The time now is 1:47 AM.