File in Use error

Feb 13, 2009 at 6:38 PM
If I am zipping up a directory/file and have a file open, I get a "The process cannot access the file '-filename-' because it is being used by another process." error.
Can I force the save of the file (or any file) regardless of whether it's in use?
Coordinator
Feb 13, 2009 at 7:29 PM
What do you mean, "you have a file open"?  Do you mean, there is a file being held open by a different process?
You cannot force the save of a file that is being held open by another process. 
You could catch the error or exception, and just skip that file.

Come to think of it, we might want DotNetZip to handle that situation automatically.  It will take some thought to design how it ought to behave. 
But for now, .... you cannot unilaterally close the file.
Feb 13, 2009 at 7:34 PM

You are correct. Say I have an excel file open from 'My Documents' and I zip up My Documents, you can get that error. I know with native windows compression, it will zip the file no matter what (which I like) and keep right on going. But native Windows Compression, well, that's about the only good feature.

So yes, if DotNetZip could zip those file no matter what (or some similar handling) that would be the cherry on top. (Well, another cherry - I like DotNetZip, good stuff.)

Coordinator
Feb 13, 2009 at 8:35 PM

Yes, zipping up files even if they are held open, makes sense to me.
I updated the library to do that. 
You will need to download v1.7.2.5 to get that new behavior.  It's available now.

Let me know.

Feb 16, 2009 at 2:27 PM
With the new dll I still seem to get the same problem - almost. Follow my troubleshooting...
I opened a Word file, ran the zip program (that compresses 'My Documents'), worked fine.
Opened a Word and Excel, failed on the Excel (same 'in use by another process error').
Opened just the excel file, failed.
Opened Access, Powerpoint, PDF, JPG worked fine.
Opened XLS file - WORKED.
Opened original XLSX file - failed.

Where it's failing is on the temp file that gets created. If I open SomeFile.xlsx, it will open a ~$SomeFile.xlsx temp file - which is where it is failing. If I open a doc or docx file, I don't have the problem. And yes, with the docx file, it also creates the ~$SomeFile.docx temp file - but it zips ok. I did try different excel files to exclude the actual file itself.

So, it would appear for some reason, that it fails ONLY on the temp file that gets created by Excel when a file is open. I'm using Office 2007. The above mentioned xls file that worked, was open with Excel 2007, but it was in Compatibility mode and saved as an xls - not the newer xlsx extension.

I'm stumped and since you're the guru, I have to rely on you.
Any ideas?



Coordinator
Feb 17, 2009 at 3:41 AM
BFJ, I'd love to help you but I don't quite get what you are doing or what is not working.

When you say "it worked" - what, exactly, worked?
You said you opened a word file and then ran a zip program and everything worked fine.  ok, good enough.

Then you said you opened "a word and excel".  Does that mean you opened Word, or you opened an existing document within Word?  Same thing with Excel - is it just opening Excel, or is it opening an Excel document? 

And then... what failed?  Excel failed to open?  Word failed to open?   Excel failed to open the file you wanted to open?  are you running a zip program in there somewhere? Is the original zip program STILL running? 
etc etc

You later wrote that you opened the original XLSX file and that failed.  How?  What failed?  Again, are you running a zip program in there somewhere?  or are you saying that excel failed to open a file?  and if so what did it say? 

I'm just not clear on what is happening.  If I were clear on what was happening I might be able to change something or advise you so that it would behave differently.
Then you started describing a temp file, and compatibility mode, and I  *really* don't understand what that is all about.

If there is a really clear way to reproduce the problem, then I can look into it.
Feb 17, 2009 at 1:36 PM
After re-reading my post, I can understand your confusion. First, sorry, secondly I'll try to be more clear.
I've created a program that zips the contents of a users My Documents directory. Originally, it worked fine if you didn't have any files open within that directory while it was being zipped. You fixed the dll to zip the files no matter what - which works except for Excel 2007 files. In my testing, I would zip the My Documents directory while I had a file (or files) open to determine whether or not I would get the debug error of '<filename> is in use by another process'. All the file types that I opened in testing, were zipped up successfully - except for an Excel 2007 file.
Whenever you open a Word file or Excel file, it creates a temp file in the same directory as the actual file opened (I assume for some editing routine built into MS Office). The temp file that is created when you open a Word file or Excel file is "~$<filename>.xlsx" (or .docx). During the zipping process of the My Documents directory, the actual Excel file and Word file gets zipped successfully, BUT the temp file that MS Office creates -for Excel only - errors with the '<filename> is in use by another process'. The Word file and temp word file zip successfully.
While Word also uses the same process of creating this temp file, the actual Word file and the temp file zip ok. So for whatever reason, the error only happens on the temp file that Excel creates when the original file opens.

Example:
If I open C:\My Documents\Bingo.xlsx a temp file is created: C:\My Documents\~$Bingo.xlsx.
I zip My Documents, C:\My Documents\Bingo.xlsx zips correctly (I can tell because I have a process that shows me which files are being zipped ok) BUT C:\My Documents\~$Bingo.xlsx errors because it's in use by another process.

To summarize, your updated dll to zip files whether they are open or not, was successful. The exception is with the Excel temp file that gets created when you open an Excel xlsx. For some reason, I still get the error '<filename> is in use by another process' ONLY for the temp excel file.

As for my code, I think I'm using it correctly, but what I do is:
On the click event of a button I call a ZipSave routine- ZipSave(My.Computer.FileSystem.SpecialDirectories.MyDocuments, filename)


Private

 

Sub ZipSave(ByVal SourceFolder As String, ByVal DestFile As String)

 

zipArchive.AddDirectory(SourceFolder)

zipArchive.CompressionLevel = Zlib.CompressionLevel.LEVEL9_BEST_COMPRESSION

zipArchive.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Always

zipArchive.Save(DestFile)

 

 

 

 

 

 

End Sub

 

Feb 17, 2009 at 2:00 PM
If this helps more:

BFJ, I'd love to help you but I don't quite get what you are doing or what is not working.

When you say "it worked" - what, exactly, worked? Your DotNetZip, I zipped up the source directory containing files.
You said you opened a word file and then ran a zip program and everything worked fine.  ok, good enough.

Then you said you opened "a word and excel".  Does that mean you opened Word, or you opened an existing document within Word?  Same thing with Excel - is it just opening Excel, or is it opening an Excel document?  Documents within Word and Excel.

And then... what failed?  Excel failed to open?  Word failed to open?   Excel failed to open the file you wanted to open?  are you running a zip program in there somewhere? Is the original zip program STILL running?  The zipping of the temp file created by EXCEL failed. The actual Excel file did zip. The Word file and it's temp file DID zip. Yes, I did try different Excel files to eliminate the file. AND, it only happened on the temp file created from an Excel 2007 file - meaning, from an .xlsx file. If I use Excel 2007 to open an .xls (older format) file, the zipping works while the file is open. Probably due to it doesn't create this temp file.
etc etc

You later wrote that you opened the original XLSX file and that failed.  How?  What failed?  Again, are you running a zip program in there somewhere?  or are you saying that excel failed to open a file?  and if so what did it say? I open files that are within the My Documents directory, then I zip the My Documents directory. The zipping stops (testing in debug mode) with the error that the file, excel temp file, was in use by another process. Your updated code fixed this problem with every file I've tested so far, except these excel temp files.

I'm just not clear on what is happening.  If I were clear on what was happening I might be able to change something or advise you so that it would behave differently.
Then you started describing a temp file, and compatibility mode, and I  *really* don't understand what that is all about. Excel\Word 2007 changed the file format from .xls/.doc to .xlsx/.docx. Using 2007 Word/Excel, you can save/open older files. When doing so, it's called compatibility mode. (basically MS fluff in the title bar of the app.)

If there is a really clear way to reproduce the problem, then I can look into it. Create a test directory, put an excel file with an xlsx extention in that directory by itself. Open the file, notice the temp file that gets created in that directory when you open the file. Now zip that directory. You will get an error on the temp file because the temp file is being used by another process.  If you repeat this same procedure with a Word file, docx extenstion, it will zip correctly.
Coordinator
Feb 19, 2009 at 2:11 AM
Got it.  All clear.  I just tried this and got the same error you reported.
Coordinator
Feb 20, 2009 at 1:39 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Feb 24, 2009 at 9:15 PM
Forgive my ignorance but when an issue becomes a work item, that means what?
Is there a way to exclude certain file types by extention or <file begins with> code?
Coordinator
Feb 25, 2009 at 7:54 AM

"work item" is a formal request for a specific piece of work.

When an issue becomes a work item, it means I am formally tracking it.  Which is good.  It also means that it is not trivial to resolve.  Which is not so good. 

If you look on the tabs across the top of the CodePlex site, you should see "Issue Tracker" . All the work items are tracked there - they are requests from users for enhancements, reports of problems, that kind of thing.  People can vote work items up, they can comment on them, upload files that show the problem, etc.  I can update the status, comment on progress, and so on. 

2nd question - is there a way to exclude certain file types. . .  You can do it manually.  You would have to recurse through your directory structure and individually add files, testing each one to see if the extension matches what you want to exclude. 

There is a separate outstanding work item to add wildcard support for the AddFile and AddDirectory methods.  A good solution there would make it simpler to include or exclude extensions.  I don't have a plan for the wildcard thing yet. 

ps: there are no dumb questions.

 

Oct 14, 2009 at 4:12 AM

Do you have an example on how I can skip a file but continue zipping?(because I'm zipping multiple files in one zip.Save)

I keep getting "The process cannot access the file 'File' because it is being used by another process." I tried:

if (e.EventType == ZipProgressEventType.Error_Saving)

in the saveprogress event handler but it doesn't get to that point and if I just do a catch it cancels the zip.

thanks for any help

Coordinator
Oct 14, 2009 at 6:44 AM

Hey Brian,

you want the ZipError event handler.

The doc for the ZipError event includes this sample code.

public static void MyZipError(object sender, ZipErrorEventArgs e)
{
    Console.WriteLine("Error saving {0}...", e.FileName);
    Console.WriteLine("   Exception: {0}", e.exception);
    ZipEntry entry = e.CurrentEntry;
    string response = null;
    // Ask the user whether he wants to skip this error or not
    do
    {
        Console.Write("Retry, Skip, Throw, or Cancel ? (R/S/T/C) ");
        response = Console.ReadLine();
        Console.WriteLine();

    } while (response != null &&
             response[0]!='S' && response[0]!='s' &&
             response[0]!='R' && response[0]!='r' &&
             response[0]!='T' && response[0]!='t' &&
             response[0]!='C' && response[0]!='c');

    e.Cancel = (response[0]=='C' || response[0]=='c');

    if (response[0]=='S' || response[0]=='s')
        entry.ZipErrorAction = ZipErrorAction.Skip;
    else if (response[0]=='R' || response[0]=='r')
        entry.ZipErrorAction = ZipErrorAction.Retry;
    else if (response[0]=='T' || response[0]=='t')
        entry.ZipErrorAction = ZipErrorAction.Throw;
}

public void SaveTheFile()
{
  using (var zip = new ZipFile())
  {
    zip.ZipError += MyZipError;
    zip.AddDirectory(directoryToZip,"fodder");
    zip.Save(zipFileToCreate);
  }
}

 

Oct 25, 2009 at 9:34 AM

To bucfanJeff.

 

Do you really need to zip these temp files? One of intentions for these files is to tell other Excel instance that certain Excel-book is currently opened for editing. If you try to open XLS (that already opened) by another Excel instance you will see question: “File is already opened by another user. Would you like to open it read-only?”

So, let assume, you’ve successfully zipped MyDocuments. Time passed. You’ve decided to unzip folder and have done with it. Everything seems to be great, but when you try to open XLS file (zipped being opened) you get surprised! Excel gladly asks you to open file in read-only mode. Just until you delete “~your_file.xls”.

By the way, it’s not a good idea to backup files opened by MS Office because of Windows file-sharing design. You may get troubles with corrupted ones. Believe my experience.  It’s better to ask user to close his stuff.

And there is simple way to exclude certain files. You have to travel through folder tree recursively using .NET. Then simple pass list of entries collected to ZipFile instance.

Forgive my English. Hope my post will help.

Alexey.

Oct 26, 2009 at 2:11 PM

Abramoth,

No, there is no need for me to backup the temp files. But my backup program does a "full" backup of My Documents, then a "partial" (files that have changed) whenever the user schedules it to run. So when the partial runs and sees the temp file is no longer there, it is removed from the archive - as it would with any file. Could I still have the problem? Sure, but the chances are low and if I'm restoring the whole archive, I probably have bigger issues than worrying about one file opening. I do appreciate the helpful post.

Thanks

Dec 9, 2009 at 1:37 PM

I'm using v1.8.4.28 and it works fine with xslx files but crashes when zipping outlook .pst files even if use ZipError event handler. Any ideas how to handle this? 

Unhandled Exception: System.IO.IOException: The process cannot access the file because another process has locked a portion of the file.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.ReadCore(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count)
   at Ionic.Zlib.CrcCalculatorStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at Ionic.Zip.SharedUtilities.ReadWithRetry(Stream s, Byte[] buffer, Int32 offset, Int32 count, String FileName)
   at Ionic.Zip.ZipEntry._WriteFileData(Stream s)
   at Ionic.Zip.ZipEntry.Write(Stream s)
   at Ionic.Zip.ZipFile.Save()
   at Ionic.Zip.ZipFile.Save(String fileName)

Dec 9, 2009 at 1:49 PM

Oops, sorry. The solution was to add

 zip.ZipErrorAction = ZipErrorAction.InvokeErrorEvent;