Link to home
Start Free TrialLog in
Avatar of mebjen
mebjen

asked on

WHAT PROCESS -- "The process cannot access the file because it is being used by another process"

In my application (VB .NET) I am continually getting the error message - "The process cannot access the file because it is being used by another process" --

My question is this - HOW CAN I FIND OUT WHAT OTHER PROCESS IS USING THE FILE???


mb
Avatar of pashcroft
pashcroft

Hmm, that's a good question, sadly i'm not aware of anyway you can.
You see, the file could be open in notepad, held by visual studio IDE, etc, etc, just about any other process could be the culprit at different times.  ie it's not just your own application's processes that can 'lock' a file.

Usually though your own processes are the culprit (especially if you are using threading).  I have actually created a processing queue to invoke 'clashable' jobs syncronously within a single thread for that very reason.  I could share that if you needed that approach.

If you want to give details on specific probs i'm happy to look at it 4 u.
Avatar of mebjen

ASKER

OK - I'll try to explain -

I have a file 3234.txt Located in C:\tvcHT - when the console app starts:

1st - it checks to see that the file exists - if True
2nd - the file is processed
3rd - a copy of the file is sent to C:tvcHT\History and named dateTime3234.txt
4th - the file is moved to C:\tvcHT\Temp

OK - with me so far -

Now - when I send another file named 3234_1.txt to C:\tvcHT - and via a fileWatcher routine Steps 1 through 4 come off without a hitch -

Typically the problem arrises on the 2nd or 3rd time that I try sending a new file.

Hope this helps in getting a visual.

mb
in step 2 when you process the file. If you open it and do not close then you will get this message. The open File can be copied to another folder, but when you try to create the file with the same name it cannot override the open file. make sure that you close file after processing
yep, i agree with that, are you calling Close() on file and any streams used to instantiate (if you're processing is not too long, post it and we'll see the prob)
also i assume you are using system.io classes to move and copy file.
Avatar of mebjen

ASKER


1st -
Public Sub chkForCfgFile()
        Dim fName As String
        Dim currCfgFile As String
        Try
            For Each fName In Directory.GetFiles(cfgDirPath, "*.txt")
                currCfgFile = fName.TrimStart("C", ":", "\", "t", "v", "c", "H", "T", "_", "C", "o", "n", "f", "i", "g")
                currCfgName = currCfgFile
            Next
        Catch objE As Exception
            Call handleExc("CConfig", objE)
        End Try

        Dim cfgFilePath As String = currCfgPath & "\" & currCfgName
        Dim cfgFile As File

        Try
            If Not cfgFile.Exists(cfgFilePath) Then
                'Console.WriteLine("Current CONFIG is Not in " & cfgFilePath)
                'Broadcast ht has no CONFIG
            Else
                ' Console.WriteLine("Current CONFIG is in C:\tvcHT\tvcHT_Config")
            End If
        Catch objE As DirectoryNotFoundException
            Call handleExc("modCfgChkHT", objE)

        Catch objE As Exception
            Call handleExc("modCfgChkHT", objE)
        End Try

    End Sub
********************************************************************************************************
2nd -
Public Sub ProcessCurrentCfg()
        Dim rdCfgLine As StreamReader = New StreamReader(cfgDirPath & "\" & currCfgName)
        Dim cntCfgLines As StreamReader = New StreamReader(cfgDirPath & "\" & currCfgName)
        Dim fileSize As Integer = rdCfgLine.Peek
        Dim delCfgFile As File
        Dim lnCounter As Integer = 0
        Dim cfgLn0() As String
        Dim cfgLn1() As String
        Dim cfgLn2() As String
        Dim cfgLn3() As String
        Dim cfgLn4() As String
        Dim cfgLn5() As String
        Dim cfgLn6() As String
        Dim stringElements As String
        Dim resultsString As String
        Dim x As Integer 'x = no. of lines in config

        '
        Do While cntCfgLines.Peek > -1
            cntCfgLines.ReadLine()
            x = x + 1
        Loop
        cntCfgLines.Close()
        Try
            If x = 7 Then 'cfg file line count must = 7
                'Read first line of cfgFile (0)
                cfgLn0 = Regex.Split(rdCfgLine.ReadLine, ",")
                u_unit = cfgLn0
                If u_unit.Length = 4 Then
                    'Progress to nextLine (1)
                    cfgLn1 = Regex.Split(rdCfgLine.ReadLine, ",")
                    resultsString = ""

                    '-------------------------------------------------------------------------------------
                    'Parse for whlPos 1
                    For Each stringElements In cfgLn1
                        resultsString += stringElements & ControlChars.CrLf
                         If cfgLn1(2) = "" Then
                            cfgLn1(2) = "0"
                        End If
                    Next
                    p_wp1 = cfgLn1

                    If p_wp1.Length = 14 Then

                        'Progress to nextLine(2)
                        cfgLn2 = Regex.Split(rdCfgLine.ReadLine, ",")
                        resultsString = ""

                        '------------------------------------------------------------------------
                        'Parse for whlPos 2
                        For Each stringElements In cfgLn2
                            resultsString += stringElements & ControlChars.CrLf
                            If cfgLn2(2) = "" Then
                                cfgLn2(2) = "0"
                            End If
                        Next
                        p_wp2 = cfgLn2

                        If p_wp2.Length = 14 Then
                            'Progress to nextLine(3)
                            cfgLn3 = Regex.Split(rdCfgLine.ReadLine, ",")
                            resultsString = ""

                            '--------------------------------------------------------------------------
                            'Parse for whlPos 3
                            For Each stringElements In cfgLn3
                                resultsString += stringElements & ControlChars.CrLf
                                If cfgLn3(2) = "" Then
                                    cfgLn3(2) = "0"
                                End If
                            Next
                            p_wp3 = cfgLn3

                            If p_wp3.Length = 14 Then
                                'Progress to nextLine(4)
                                cfgLn4 = Regex.Split(rdCfgLine.ReadLine, ",")
                                resultsString = ""

                                '------------------------------------------------------------------------------
                                'Parse for whlPos 4
                                For Each stringElements In cfgLn4
                                    resultsString += stringElements & ControlChars.CrLf
                                    If cfgLn4(2) = "" Then
                                        cfgLn4(2) = "0"
                                    End If
                                Next
                                p_wp4 = cfgLn4

                                If p_wp4.Length = 14 Then
                                    'Progress to nextLine(5)
                                    cfgLn5 = Regex.Split(rdCfgLine.ReadLine, ",")
                                    resultsString = ""

                                    '-------------------------------------------------------------------------------------
                                    'Parse for whlPos 5
                                    For Each stringElements In cfgLn5
                                        resultsString += stringElements & ControlChars.CrLf
                                       If cfgLn5(2) = "" Then
                                            cfgLn5(2) = "0"
                                        End If
                                    Next
                                    p_wp5 = cfgLn5

                                    If p_wp5.Length = 14 Then
                                        'Progress to nextLine(6)
                                        cfgLn6 = Regex.Split(rdCfgLine.ReadLine, ",")

                                        '-----------------------------------------------------------------------------------
                                        'Parse for whlPos 6
                                        For Each stringElements In cfgLn6
                                            resultsString += stringElements & ControlChars.CrLf
                                            If cfgLn6(2) = "" Then
                                                cfgLn6(2) = "0"
                                            End If
                                        Next
                                        p_wp6 = cfgLn6
                                        If Not p_wp6.Length = 14 Then
                                            cfgError("cfgProcessing: ", "ERROR: LINE 6 (wp6) - LineLengthError(" & p_wp6.Length & "):" & " <> 14")
                                        End If 'p_wp6
                                    Else
                                        cfgError("cfgProcessing: ", "ERROR: LINE 5 (wp5) - LineLengthError(" & p_wp5.Length & "):" & " <> 14")
                                    End If 'p_wp5
                                Else
                                    cfgError("cfgProcessing: ", "ERROR: LINE 4 (wp4) - LineLengthError(" & p_wp4.Length & "):" & " <> 14")
                                End If 'p_wp4
                            Else
                                cfgError("cfgProcessing: ", "ERROR: LINE 3 (wp3) - LineLengthError(" & p_wp3.Length & "):" & " <> 14")
                            End If 'p_wp3
                        Else
                            Call cfgError("cfgProcessing: ", "ERROR: LINE 2 (wp2) - LineLengthError(" & p_wp2.Length & "):" & " <> 14")
                        End If 'p_wp2
                    Else
                        Call cfgError("cfgProcessing: ", "ERROR: LINE 1 (wp1) - LineLengthError(" & p_wp1.Length & "):" & " <> 14")
                        Do
                            Console.WriteLine("GotIt")
                        Loop

                    End If 'p_wp1
                Else
                    Call cfgError("cfgProcessing: ", "ERROR: LINE 0 (unitInfo) - LineLengthError(" & u_unit.Length & "):" & " <> 14")
                End If 'u_unit
            Else
                Call cfgCorrupt("cfgProcessing: ", "ERROR: FileLength - FileLineCount(" & x & "):" & " <> 7")
                End If 'cfgFile line count

            If u_unit.Length = 4 And p_wp1.Length = 14 And p_wp2.Length = 14 And p_wp3.Length = 14 And _
                                     p_wp4.Length = 14 And p_wp5.Length = 14 And p_wp6.Length = 14 Then
                'record succession in cfgLog file
                Call cfgValid("CConfig: ") 'modCentralExc
            End If

        Catch objE As Exception
            Call handleExc("ProcessCurrentCfg", objE) 'modCentralExc
        End Try
        rdCfgLine.Close()
        cntCfgLines.Close()
        sendCopyToCfgHistory()
        delCfgFile.Delete(cfgDirPath & "\" & currCfgName)
    End Sub  'ProcessCurrentCfg
****************************************************************************************************
3rd -
Private Sub sendCopyToCfgHistory()
        Dim dt As DateTime = DateTime.Now
        Dim dtYY As String = dt.Year
        Dim dtDOY As String = dt.DayOfYear
        Dim dtTimeHH As String = dt.Hour
        Dim dtTimeMM As String = dt.Minute
        Dim dtTimeSS As String = dt.Second
        Dim cfgFileCopySource As String = copySrceCfgPath & "\" & currCfgName
        '07/12 - added dateTime to file name being copied to historyFile
        'cfgHistoryFileName = 2004|192|13|22|04|33013.txt (YYYY|dayOfYear|Hour|Minute|Second|trkId|.txt
        Dim cfgFileCopyDest As String = cfgHistDirPath & "\" & dtYY + dtDOY + dtTimeHH _
                                                       + dtTimeMM + dtTimeSS + currCfgName
        Dim cSrce As File
        Try
            cSrce.Copy(cfgFileCopySource, cfgFileCopyDest)
            Console.WriteLine("A copy of the current config as been saved to C:\tvcHT\tvcHT_Config\History")
        Catch objE As Exception
            Call handleExc("CConfig \ sendCopyToCfgHistory", objE)
        Finally
            cfgFileCopySource = Nothing
            cfgFileCopyDest = Nothing
            System.GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try

    End Sub
**************************************************************************************
4th -
Private Sub copyCfgToTemp()
        Dim cfgTempDest As String = cfgTempPath & "\" & currCfgName
        Dim cfgFileSource As String = copySrceCfgPath & "\" & currCfgName
        Dim tempCfg As String = cfgTempPath & "\" & tempCfgName
        Dim tFile As String
        Dim tempFileName As String
        Dim delTempFile As File
        Dim fSrce As File
        Try
            If Not fSrce.Exists(cfgFileSource) Then
                Console.WriteLine("A Copy  of the current config could not be saved.")
                ' Console.WriteLine("")
            Else
                'Need to get and set unique tempCfgFile Name
                For Each tFile In Directory.GetFiles(cfgTempPath, "*.txt")
                    tempFileName = tFile
                    tempCfgName = tempFileName
                    delTempFile.Delete(tempCfgName)
                Next
                fSrce.Move(cfgFileSource, cfgTempDest)
                Console.WriteLine("File has been moved to Temp Dir")
            End If
        Catch objE As Exception
            Call handleExc("CConfig \ moveToTemp", objE)
        Finally
            cfgTempDest = Nothing
            cfgFileSource = Nothing
            tempCfg = Nothing

        End Try
    End Sub

mb
ASKER CERTIFIED SOLUTION
Avatar of pashcroft
pashcroft

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mebjen

ASKER

pashcroft,

I made the changes as per your suggestion - unfortunately - I still get the same results after the 2nd time running.


mb
out of curiosity ... howlong does the issue persist for ? the filewatcher will give you results when the file is created, it may still be being written to ...

example...

copy foo bar

Filewatcher raises at the create ... when you try to open bar, copy is still copying the data into it, thus has an exclusive lock.

also im just curious about this ...

                        Do
                            Console.WriteLine("GotIt")
                        Loop

Avatar of Bob Learned
I don't see any .Dispose calls anywhere.  If you call .Dispose, then you don't have to worry about forcing garbage collection.

Bob
Hey Bob!

I had the same problem and your solution worked like a charm! I have a picturebox that displayed an image stored in a file. I was making the picturebox null before trying to delete the file, but it didn't work. I used .Dispose and it works! Awesome!! :-)

Taarik.
TZRick: Image.FromFile() puts a lock on the file. You can avoid this lock by opening the file yourself and using Image.FromStream() ..

this will alleviate the need for the Dispose() although you should always call dispose on any object that implements IDisposable ... the Dispose() method get called when garbage collection runs accross that object which is why garbage collection "seemingly" solves the issu.