1

Title explains a small part so let me explain 2 scenarios. Scenario 1 is raising errors, scenario 2 works like a charm.

Scenario 1:

I checkout a document with the method below, when the document is saved to a location where already is a file with that name it gets overwritten, But surprisingly it also locks the file for some reason:

public bool SaveDocument(int bestandsId, string fileName, string path)
{
    //Initialize the Sql Query
    var sql = "SELECT DATA FROM Documenten WHERE BESTAND_ID = " + bestandsId;
    //Initialize SqlConnection
    var connection = new SqlConnection(Instellingen.Instance.DmsConnectionString);
    //Initialize SqlCommand
    var command = new SqlCommand(sql, connection);

    try
    {
        //Open Connection
        connection.Open();
        //Fill 'data' from command.ExecuteScalar()
        var data = (byte[]) command.ExecuteScalar();
        //Write 'data' to file.
        File.WriteAllBytes(path + @"\" + fileName, data);
        //Return true if no exceptions are raised.
        return true;
    }
    catch (Exception ex)
    {
        //Initialize Dms Exception
        var dmsEx = new DmsException(ex);
        //Write Dms Exception to Log File.
        DmsException.WriteErrorsToLog(dmsEx);
        //Return false, because something went wrong...
        return false;
    }
    finally
    {
        //Close Sql Connection
        connection.Close();
    }
}

The method runs smoothly. No problems occur. But when I check in the document with the method below, I get this exception:

Exception

Scenario 2:

When I use the SaveDocument method to save the document to a location where there isn't a file with the same name, the file is newly created and is ready to be edited or what ever you want to do with it.

Using scenario 2 is working perfect. The document is ready to be checked in again without receiving an error as shown in the picture above.

Request for code by: @CodeCaster

---------------------------------BEGIN EDIT---------------------------------

    public static bool InsertDocument(Document document)
    {
        try
        {
            //Exception is thrown when Initializing the FileStream
            var fileStream = new FileStream(document.Fileinfo.FullName, FileMode.Open, FileAccess.Read); 

            var binaryReader = new BinaryReader(fileStream);
            var totalNumberOfBytes = new FileInfo(document.Fileinfo.FullName).Length;
            var data = binaryReader.ReadBytes((Int32) totalNumberOfBytes);

            fileStream.Close();
            fileStream.Dispose();
            binaryReader.Close();
            binaryReader.Dispose();

            var pdftext = string.Empty;
            try
            {
                if (document.DocumentType == ".pdf")
                {
                    var reader = new PdfReader(document.Fileinfo.FullName);
                    var text = string.Empty;
                    for (var page = 1; page <= reader.NumberOfPages; page++)
                    {
                        text += PdfTextExtractor.GetTextFromPage(reader, page);
                    }
                    reader.Close();
                    pdftext = text;
                }
            }
            catch (Exception ex)
            {
                var dmsEx = new DmsException(ex);
                DmsException.WriteErrorsToLog(dmsEx);
            }


            return InsertIntoDatabase(document.BestandsNaam, document.Eigenaar, document.Omschrijving,
                                      document.DatumToevoeg.ToString(), document.DatumIncheck.ToString(),
                                      document.DatumUitcheck.ToString(), document.UitgechecktDoor,
                                      document.DocumentType, data, pdftext, document.Versie, document.Medewerker,
                                      document.DossierNummer, document.PersonalFolderId.ToString(),
                                      document.DossierFolderId, -1, document.DocumentProgres,
                                      document.OriBestandId.ToString(), 0);
        }
        catch (Exception ex)
        {
            var dmsEx = new DmsException("Fout bij inlezen voor toevoeging van nieuw document",
                                         "Klasse Document (InsertDocument)", ex);
            ExceptionLogger.LogError(dmsEx);

            return false;
        }
    }

---------------------------------END EDIT---------------------------------

My questions:

  1. What is the cause for the file being locked when it gets overwritten?
  2. How can I prevent this from happening?
  3. Is there some sort of function or parameter that I can set so it doesn't get locked?

Using a tool called "Unlocker" I managed to see what program is locking the file, and YES -> DMS.exe is my application.......: enter image description here

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
ValarmorghulisHQ
  • 989
  • 1
  • 11
  • 31
  • 5
    That's a lovely SQL injection vulnerability you've built. Please parameterize your SQL statements. – Daniel Mann Dec 20 '13 at 13:32
  • @RaZor he said please! :P – C.Evenhuis Dec 20 '13 at 13:34
  • @RaZor I was just trying to lighten the mood. Aside from parameterizing being a good thing, I've never seen an `int` cause an SQL injection vulnerability in the first place. – C.Evenhuis Dec 20 '13 at 13:41
  • If you use StreamWriter the same problem happens? (using "using" statement xD) Is there any thread running on this code? – briba Dec 20 '13 at 13:41
  • The code you showed does not leave the file in use. Please show the code throwing the exception. – CodeCaster Dec 20 '13 at 13:47
  • Many suggestion on this subject blame the virus-scanner. Have you tried putting in some waiting time before check-in (temp solution to verify if it gets unlock after a small amount of time ?) – tazyDevel Dec 20 '13 at 14:03
  • @tazyDevel I'm not using a virusscanner. Doesn't matter if I wait 1 minute, 1 hour or 1 day.. File is still in use... Look at the picture I've added which shows that my application is locking the file. – ValarmorghulisHQ Dec 20 '13 at 14:08
  • `System.IO.File.WriteAllBytes("Foo.bar", new byte[] { 42 });` followed by `var fileStream = new System.IO.FileStream("Foo.bar", System.IO.FileMode.Open, System.IO.FileAccess.Read);` does not throw. There _must_ be file access code be called in between those two calls. – CodeCaster Dec 20 '13 at 15:39
  • I've been searching for other places where the code might keep the file in use but so far I haven't found anything..... I'm not sure whats going on here... – ValarmorghulisHQ Dec 23 '13 at 08:29

1 Answers1

-2
using(var stream = File.Create(newPath)){}
File.WriteAllBytes(newPath, item.File);

With StreamWriter

using (FileStream fs = File.Create(newPath))
{
    fs.Write(item.File, 0, item.File.Length);
}

Or:

File.WriteAllBytes(newPath, item.File);

Reference: "The process cannot access the file because it is being used by another process" with Images

Community
  • 1
  • 1
briba
  • 2,857
  • 2
  • 31
  • 59
  • The problem in that question is `File.Create()` returning a stream to the file, leaving the file locked. `File.WriteAllBytes()` has no such problem. – CodeCaster Dec 20 '13 at 13:47