I created an app that does the following:
- Opens an excel spreadsheet and show a hidden sheet
 - Copy the data in this sheet to a temporary spreadsheet
 - Run some error checks on the data that's been pasted
 - Create a unique code in the first column based on customer no. date & time
 - Save the spreadsheet as a new file
 - Clear up to be ready for the next spreadsheet
 
The problem I am having is at step 6 of clearing up and releasing any excel objects in memory that can hold up moving to the next spreadsheet and so on. The current issue I have is that an Excel object remains open and locks the tempfile.xlsx that is created which will then randomly generates the error "The file 'C:\Temp\CustOrders\Input\TempFile.xlsx' already exists." I say randomly because I can run 10 or more files through it without an issue. I could run them all again and it will produce the error after the 1st, 2nd, 3rd or later file. I cannot blame any one file for causing this.
How do I effectively close out all Excel objects ready for the next file to be processed? I have so far tried different ways to do this including trying to kill the process but this seems like a dirty sledgehammer approach.
Here's the code:
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Imports System.IO
Public Class Form1
    Dim xlApp As Excel.Application
    Dim xlNewApp As Excel.Application
    Dim xlWorkBook As Excel.Workbook
    Dim xlWorkSheet As Excel.Worksheet
    Dim range As Excel.Range
    Dim rCnt As Integer
    Dim cCnt As Integer
    Dim Obj As Object
    Dim TempFile() As String
    Dim TempFiledir As String
    Dim filename As String
    Dim xlNewWorkBook As Excel.Workbook
    Dim xlNewWorkSheet As Excel.Worksheet
    Dim misValue As Object = System.Reflection.Missing.Value
    Dim Cust As Object
    Dim pfile As String
    Dim NoProcessed As Integer = 0
    Dim NoFailed As Integer = 0
    Dim filecount As Integer = 0
    Dim fileremaining As Integer = 0
    Dim custFailed As Integer = 0
    Dim files() As String = Directory.GetFiles("C:\Temp\CustOrders\Uploaded")
    Dim di As New DirectoryInfo("C:\Temp\CustOrders\Uploaded")
    Private Sub releaseObject(ByVal obj As Object)
        Try
            Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        lblProcessingFile.Visible = False
        CountFiles()
        lblFileCount.Text = "Files to be processed: " & filecount
    End Sub
    Function CountFiles()
        Dim files() As String = Directory.GetFiles("C:\Temp\CustOrders\Uploaded")
        Dim di As New DirectoryInfo("C:\Temp\CustOrders\Uploaded")
        If files.Count > 0 Then
            filecount = di.GetFiles("*.xlsx").Count()
        Else
            filecount = 0
            lblFileCount.Text = "Files to be processed: " & filecount
        End If
    End Function
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles BTN_gencsv.Click
        TempFiledir = ("C:\Temp\CustOrders\Input\TempFile.xlsx")
        If My.Computer.FileSystem.FileExists(TempFiledir) Then
            My.Computer.FileSystem.DeleteFile(TempFiledir)
        End If
        GetFiles()
    End Sub
    Sub GetFiles()
        '1. Look in the UPLOADED folder for new files
        
        Dim files() As String = Directory.GetFiles("C:\Temp\CustOrders\Uploaded")
        Dim di As New DirectoryInfo("C:\Temp\CustOrders\Uploaded")
        If files.Count > 0 Then
            Dim arrayfi As FileInfo() = di.GetFiles("*.xlsx")
            Dim fi As FileInfo
            For Each fi In arrayfi
                filename = fi.Name
                Start(filename)
            Next
        Else
            MsgBox("No files available in directory")
        End If
    End Sub
    Sub Start(filename)
        With BTN_gencsv
            .BackColor = Color.Red
            .ForeColor = Color.White
            .Text = "Please wait..."
        End With
        '2. Get the file that has been uploaded by the customer, copy and rename as TempFile
        lblProcessingFile.Visible = True
        lblProcessingFile.Text = "Processing file: " & filename
        IO.File.Copy("C:\Temp\CustOrders\Uploaded\" & filename, _
                                                            "C:\Temp\CustOrders\Input\TempFile.xlsx")
        xlApp = New Excel.Application
        xlNewApp = New Excel.Application
        xlWorkBook = xlApp.Workbooks.Open("C:\Temp\CustOrders\Input\TempFile.xlsx")
        xlWorkSheet = xlWorkBook.Worksheets(1)
        xlWorkSheet = xlWorkBook.Worksheets("CSV")
        xlWorkSheet.Visible = XlSheetVisibility.xlSheetVisible
        xlWorkSheet.Unprotect("opencsv")
        '3. Copy rows from the CSV worksheet including headers
        xlWorkSheet.Range("A1:H100").Copy()
        '4. Create new Excel workbook and worksheet so it can have have all rows pasted in
        '   Then perform all prep work
        xlNewWorkBook = xlNewApp.Workbooks.Add(misValue)
        xlNewWorkSheet = xlNewWorkBook.Worksheets(1)
        xlNewWorkSheet.Select()
        ' Paste the rows into the new worksheet
        On Error Resume Next
        xlNewWorkSheet.PasteSpecial(Excel.XlPasteType.xlPasteValues)
        xlApp.CutCopyMode = False
        ' Get current date/time
        Dim dt As DateTime = DateTime.Now
        Dim dt2 As String = dt
        dt2 = dt2.Replace("/", "").Replace(" ", "_").Replace(":", "")
        ' Select customer number from worksheet
        Dim xRng As Excel.Range = CType(xlNewWorkSheet.Cells(2, 5), Excel.Range)
        Cust = xRng.Value().ToString()
        ' If the customer is not found in the spreadsheet lookup it generates "-2146826246" as a value
        ' This saves the cell as "Not found" to make it look friendly
        If Cust.Equals("-2146826246") Then
            custFailed += 1
            Cust = "Cust_Not_Found_" & custFailed
            failedfiles()
        Else
            CustNo()
        End If
        releaseObject(xRng)
        ' This now passes to two error checking subs
    End Sub
    Sub completeform()
        '5. Generate a unique value for Netsuite based on the customer number and current date time
        
        Dim Row As Range
        Dim Index As Long
        Dim Count As Long
        For Index = xlNewWorkSheet.UsedRange.Rows.Count To 1 Step -1
            Row = xlNewWorkSheet.UsedRange.Rows(Index)
            Count = 0
            On Error Resume Next
            Count = Row.SpecialCells(XlCellType.xlCellTypeBlanks).Count
            If Count = Row.Cells.Count Then Row.Delete(Excel.XlDirection.xlUp)
        Next
        Dim dt As DateTime = DateTime.Now
        Dim dt2 As String = dt
        dt2 = dt2.Replace("/", "").Replace(" ", "_").Replace(":", "")
        pfile = (Cust + "_" + dt2)
        Dim rw As Integer = 1
        Do Until xlNewWorkSheet.Cells(rw, 1).Value Is Nothing
            rw += 1
        Loop
        Dim last As String = rw - 1
        With xlNewWorkSheet.Range("A1:A100")
            .Range(.Cells(2, 1), .Cells(last, 1)).Value = (Cust + "_" + dt2)
        End With
        '6. Save the workbook with a unique name based on customer number and date/time
        xlWorkBook.Saved = True
        xlNewWorkBook.SaveAs("C:\Temp\CustOrders\Output\Test_" + pfile + ".csv", Excel.XlFileFormat.xlCSV, misValue, misValue, misValue, misValue, _
                 Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)
        '7. Close and release all Excel worksheets and workbooks so they dont remain in memory
        xlNewWorkBook.Close(True, misValue, misValue)
        xlWorkBook.Saved = True
        xlNewWorkBook.Saved = True
        releaseObject(xlNewWorkSheet)
        releaseObject(xlNewWorkBook)
        releaseObject(xlNewApp)
        xlWorkBook.Close(False)
        xlApp.Quit()
        releaseObject(range)
        releaseObject(xlWorkSheet)
        releaseObject(xlWorkBook)
        releaseObject(xlApp)
        xlNewApp.Quit()
        System.Threading.Thread.Sleep(2000)
        '8. Move the processed workbook to the Processed folder ready for a new workbook
        IO.File.Move("C:\Temp\CustOrders\Input\TempFile.xlsx", _
                                                "C:\Temp\CustOrders\Processed\Processedfile_" + pfile + ".xlsx")
        '9. Move the spreadsheet from Uploaded to OldUploaded ready for a new file
        IO.File.Move("C:\Temp\CustOrders\Uploaded\" + filename, _
                                                "C:\Temp\CustOrders\OldUploaded\Uploaded_" + filename)
        
        NoProcessed += 1
        lblProcessedCount.Text = "No. Processed..." & NoProcessed
        CountFiles()
        lblFileCount.Text = "Files to be processed: " & filecount
        With BTN_gencsv
            .BackColor = SystemColors.Control
            .ForeColor = SystemColors.ControlText
            .Text = "Generate CSV"
        End With
        lblProcessingFile.Visible = False
    End Sub
    Sub CustNo()
        Dim c As Range
        With xlNewWorkSheet.Range("A1:A100")
            c = .Find("#N/A", LookIn:=XlFindLookIn.xlValues)
            If Not c Is Nothing Then
                custFailed += 1
                Cust = "Cust_Not_Found_" & custFailed
                MsgBox(Cust)
                failedfiles()
            Else
                quantityBlanks()
            End If
        End With
    End Sub
    Sub quantityBlanks()
        Dim rw As Integer = 1
        Do Until xlNewWorkSheet.Cells(rw, 1).Value Is Nothing
            rw += 1
        Loop
        Dim last As String = rw - 1
        Dim rng As Excel.Range
        Dim TotalBlanks As Long
        TotalBlanks = 0
        rng = xlNewWorkSheet.Range(xlNewWorkSheet.Cells(2, 8), xlNewWorkSheet.Cells(last, 8))
        On Error Resume Next
        TotalBlanks = rng.SpecialCells(XlCellType.xlCellTypeBlanks).Count
        If TotalBlanks > 0 Then
            Cust = "Quantity_error_"
            failedfiles()
        Else
            referrors()
        End If
        rng = Nothing
    End Sub
    Sub referrors()
        Dim c As Range
        With xlNewWorkSheet.Range("A1:A100")
            c = .Find("#REF!", LookIn:=XlFindLookIn.xlValues)
            If Not c Is Nothing Then
                Cust = "~REF!_errors_"
                failedfiles()
            Else
                completeform()
            End If
        End With
    End Sub
    Sub failedfiles()
        Dim dt As DateTime = DateTime.Now
        Dim dt2 As String = dt
        dt2 = dt2.Replace("/", "").Replace(" ", "_").Replace(":", "")
        pfile = (Cust + "_" + dt2)
        xlWorkBook.Close(False)
        xlNewWorkBook.Close(False)
        xlNewApp.Quit()
        xlApp.Quit()
        releaseObject(xlApp)
        releaseObject(xlWorkBook)
        releaseObject(xlWorkSheet)
        releaseObject(xlNewApp)
        releaseObject(xlNewWorkBook)
        releaseObject(xlNewWorkSheet)
        'IO.File.Delete("C:\Temp\CustOrders\Input\Newfile.xlsx")
        IO.File.Move("C:\Temp\CustOrders\Input\TempFile.xlsx", _
                                                "C:\Temp\CustOrders\Processed\ProcessedFailedfile_" + pfile + ".xlsx")
        IO.File.Move("C:\Temp\CustOrders\Uploaded\" + filename, _
                                        "C:\Temp\CustOrders\Failed\FailedFile_" + pfile + ".xlsx")
        With BTN_gencsv
            .BackColor = SystemColors.Control
            .ForeColor = SystemColors.ControlText
            .Text = "Generate CSV"
        End With
        NoFailed += 1
        lblFailed.ForeColor = Color.Red
        lblFailed.Text = "No. Failed..." & NoFailed
        CountFiles()
        lblFileCount.Text = "Files to be processed: " & filecount
        lblProcessingFile.Visible = False
    End Sub
    Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click
        CountFiles()
        lblFileCount.Text = "Files to be processed: " & filecount
    End Sub
End Class