Ciao a tutti,
ho un problemino con la gestione apertura/chiusura un database access.

Da VB.NET apro il DB con la seguente funzione:
codice:
 
Public Sub ApriFileAccess(ByRef accApp As Access.Application, ByVal file As String, ByVal visibile As Boolean)
        accApp = New Access.ApplicationClass()
        accApp.OpenCurrentDatabase(file, True)
        accApp.Visible = visibile        
    End Sub
Dopo aver aperto correttamente il file scarico l'elenco di tutte le tabelle, query e macro presenti nel file con questa funzione (posto tutto il codice, magari puo' interessare a qualcuno):
codice:
 
Dim connessione As ADOX.Catalog = New ADOX.Catalog
    Dim contRighe As Integer
    Dim xlsApp As Excel.Application
    Dim xlsBook As Excel.Workbook
    Dim accApp As Access.Application
    Public Const PercorsoMacro As String = "C:\ChannelStrategy\MacroTestuali\"

    Public Structure Tabella
        Dim Nome As String
        Dim Link As String
    End Structure

    Public Const QUERY_SELECT As Integer = 1
    Public Const QUERY_CROSS As Integer = 2
    Public Const QUERY_DELETE As Integer = 3
    Public Const QUERY_UPDATE As Integer = 4
    Public Const QUERY_APPEND As Integer = 5
    Public Const QUERY_MAKE As Integer = 6
    Public Structure Query
        Dim Nome As String
        Dim SQL As String
        Dim Tipo As Integer
    End Structure

    Public Const AZIONE_SETWARNING As Integer = 1
    Public Const AZIONE_OPENQUERY As Integer = 2
    Public Const AZIONE_CLOSE As Integer = 3
    Public Const AZIONE_TRANSFERSPREADSHEET As Integer = 4
    Public Const AZIONE_SENDOBJECT As Integer = 5
    Public Const AZIONE_MSGBOX As Integer = 6
    Public Structure Azione
        Dim NomeAzione As String
        Dim TipoAzione As Integer
        Dim ListaArgument() As Object
        Dim ContArgument As Integer
    End Structure

    Public Structure Macro
        Dim NomeMacro As String
        Dim ListaAzioni() As Azione
        Dim ContAzioni As Integer
    End Structure

    Public ListaTabelle() As Tabella
    Public ListaQuery() As Query
    Public ListaMacro() As Macro

    Public contTabelle As Integer
    Public contQuery As Integer
    Public contMacro As Integer
    Public contAzioni As Integer
    Public contArgument As Integer

Private Sub DammiDatiDataBase()
        Dim Contenitore As Container
        Dim Documento As Document
        Dim sr As StreamReader = Nothing
        Dim riga As String
        Dim arrRiga() As String
        Dim i, j As Integer

        ' Apro il file access invisibile
        lblAttesaOperazione.Text = "Connessione al db in corso"
        Me.Update()
        ApriFileAccess(accApp, ProprietaFile.PercorsoLocale & ProprietaFile.NomeFile, False)
        accApp.Visible = False

        ' Ottengo la lista di tutte le tabelle
        lblAttesaOperazione.Text = "Ottengo la lista di tutte le tabelle"
        Me.Update()
        contTabelle = 0
        For i = 0 To accApp.CurrentDb.TableDefs.Count - 1
            If Not accApp.CurrentDb.TableDefs(i).Name.StartsWith("MSys") Then
                contTabelle = contTabelle + 1
                Array.Resize(ListaTabelle, contTabelle)
                ListaTabelle(contTabelle - 1).Nome = accApp.CurrentDb.TableDefs(i).Name
                If accApp.CurrentDb.TableDefs(i).Connect = "" Then
                    ListaTabelle(contTabelle - 1).Link = ""
                Else
                    arrRiga = accApp.CurrentDb.TableDefs(i).Connect.Split("=")
                    If arrRiga(0).StartsWith("Text") Then
                        ListaTabelle(contTabelle - 1).Link = arrRiga(arrRiga.GetUpperBound(0)) & ".txt"
                    Else
                        ListaTabelle(contTabelle - 1).Link = arrRiga(arrRiga.GetUpperBound(0))
                    End If
                End If
            End If
        Next

        ' Ottengo la lista di tutte le query
        lblAttesaOperazione.Text = "Ottengo la lista di tutte le query"
        Me.Update()
        contQuery = accApp.CurrentDb.QueryDefs.Count
        Array.Resize(ListaQuery, contQuery)
        For i = 0 To contQuery - 1
            ListaQuery(i).Nome = accApp.CurrentDb.QueryDefs(i).Name
            ListaQuery(i).SQL = accApp.CurrentDb.QueryDefs(i).SQL
            If StrComp("SELECT", ListaQuery(i).SQL.Substring(0, 6)) Then
                ListaQuery(i).Tipo = QUERY_SELECT
            ElseIf StrComp("TRANSFORM", ListaQuery(i).SQL.Substring(0, 9)) Then
                ListaQuery(i).Tipo = QUERY_CROSS
            ElseIf StrComp("DELETE", ListaQuery(i).SQL.Substring(0, 6)) Then
                ListaQuery(i).Tipo = QUERY_DELETE
            ElseIf StrComp("UPDATE", ListaQuery(i).SQL.Substring(0, 6)) Then
                ListaQuery(i).Tipo = QUERY_UPDATE
            ElseIf StrComp("INSERT", ListaQuery(i).SQL.Substring(0, 6)) Then
                ListaQuery(i).Tipo = QUERY_APPEND
            ElseIf ListaQuery(i).SQL.Contains("INTO") Then
                ListaQuery(i).Tipo = QUERY_MAKE
            End If
        Next

        ' Scarico i contenuti di tutte le macro presenti
        lblAttesaOperazione.Text = "Ottengo la lista di tutte le macro"
        Me.Update()
        Directory.CreateDirectory(PercorsoMacro)
        contMacro = 0
        Contenitore = accApp.CurrentDb.Containers("Scripts")
        For j = 0 To Contenitore.Documents.Count - 1
            Documento = Contenitore.Documents(j)
            If Not Documento.Name.StartsWith("~") Then
                contAzioni = 0
                contMacro = contMacro + 1
                Array.Resize(ListaMacro, contMacro)
                ' Salvo la macro come file di testo
                accApp.Application.SaveAsText(Access.AcObjectType.acMacro, Documento.Name, PercorsoMacro & Documento.Name & ".txt")
                ListaMacro(contMacro - 1).NomeMacro = Documento.Name
                sr = New StreamReader(PercorsoMacro & Documento.Name & ".txt")
                riga = sr.ReadLine()
                While Not riga Is Nothing
                    If riga = "Begin" Then
                        contArgument = 0
                        contAzioni = contAzioni + 1
                        Array.Resize(ListaMacro(contMacro - 1).ListaAzioni, contAzioni)
                        riga = sr.ReadLine()
                        arrRiga = riga.Split("=")
                        riga = arrRiga(1).Substring(1, arrRiga(1).Length - 2)

                        ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).NomeAzione = riga
                        Select Case riga
                            Case "SetWarnings"
                           
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).TipoAzione = AZIONE_SETWARNING
                                contArgument = 1
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ContArgument = contArgument
                                Array.Resize(ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument, contArgument)
                                Do
                                    riga = sr.ReadLine()
                                    arrRiga = riga.Split("=")
                                Loop While Not arrRiga(0).Contains("Argument")
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(contArgument - 1) = arrRiga(1).Substring(1, arrRiga(1).Length - 2)

                                'vado fino a end
                                Do
                                    riga = sr.ReadLine()
                                    arrRiga = riga.Split("=")
                                Loop While arrRiga(0) <> "End"
                            Case "OpenQuery"
                                
                                ' mi interessa solamente il primo Argument
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).TipoAzione = AZIONE_OPENQUERY
                                contArgument = 1
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ContArgument = contArgument
                                Array.Resize(ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument, contArgument)
                                Do
                                    riga = sr.ReadLine()
                                    arrRiga = riga.Split("=")
                                Loop While Not arrRiga(0).Contains("Argument")
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(contArgument - 1) = arrRiga(1).Substring(1, arrRiga(1).Length - 2)

                                'vado fino a end
                                Do
                                    riga = sr.ReadLine()
                                    arrRiga = riga.Split("=")
                                Loop While arrRiga(0) <> "End"
                            Case "Close"

                            Case "MsgBox"
                               
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).TipoAzione = AZIONE_OPENQUERY
                                contArgument = 4
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ContArgument = contArgument
                                Array.Resize(ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument, contArgument)
                                Do
                                    riga = sr.ReadLine()
                                    arrRiga = riga.Split("=")
                                Loop While Not arrRiga(0).Contains("Argument")
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(0) = arrRiga(1).Substring(1, arrRiga(1).Length - 2)
                                riga = sr.ReadLine()
                                arrRiga = riga.Split("=")
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(1) = arrRiga(1).Substring(1, arrRiga(1).Length - 2)
                                riga = sr.ReadLine()
                                arrRiga = riga.Split("=")
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(2) = arrRiga(1).Substring(1, arrRiga(1).Length - 2)
                                riga = sr.ReadLine()
                                arrRiga = riga.Split("=")
                                ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(3) = arrRiga(1).Substring(1, arrRiga(1).Length - 2)
                                'vado fino a end
                                Do
                                    riga = sr.ReadLine()
                                    arrRiga = riga.Split("=")
                                Loop While arrRiga(0) <> "End"
                        End Select
                    End If
                    riga = sr.ReadLine()
                End While
                ListaMacro(contMacro - 1).ContAzioni = contAzioni
                sr.Close()
                sr = Nothing
            End If
            System.Runtime.InteropServices.Marshal.ReleaseComObject(Documento)
            Documento = Nothing
        Next j
        Directory.Delete(PercorsoMacro, True)

        ' Chiudo il file access
        lblAttesaOperazione.Text = "Chiusura DataBase"
        Me.Update()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(Contenitore)
        Contenitore = Nothing
        ChiudiFileAccess(accApp)
    End Sub
Alla fine c'è la funzione ChiudiFileAccess che dovrebbe chiudere l'applicazione aperta accApp:

codice:
Public Sub ChiudiFileAccess(ByRef accApp As Access.Application)
        accApp.CurrentDb.Close()
        accApp.CloseCurrentDatabase()
        accApp.Quit(Access.AcQuitOption.acQuitSaveNone)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(accApp)
        accApp = Nothing

        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
PROBLEMA:
Quando arrivo al comando GC.Collect() viene visualizzata la schermata di access senza nessun DB aperto e se controllo nel Task Manager il processo MSACCESS è ancora in uso.
Quindi quando ritento per qualche ragione a riaprire il file (sono in modalità esclusiva) ovviamente mi da errore.
Cosa sbaglio? Grazie in anticipo

Andrea