Search code examples
c#openoffice.orgopenoffice-writer

Unregistering datasource and deleting associated CSV file


I'm automating a mailmerge process which uses a CSV file. Part of this process requires creating a database (OpenOffice odb file) and then registering this as a datasource. When I come to delete the database I get an exception stating 'Cannot delete yourFile:It is being used by another person or program'. The problem is that I cannot get the OpenOffice process to release this resource (without killing it). My current code is:

public string DeleteDatasource(string datasourceName)
    {
        string result = string.Empty;
        object databaseContext = _MultiServiceFactory.createInstance("com.sun.star.sdb.DatabaseContext");;
        try
        {
            XDatabaseRegistrations databaseRegistrations = (XDatabaseRegistrations)databaseContext;
            if(databaseRegistrations.hasRegisteredDatabase(datasourceName))
            {
                /*  //attempt one
                XNameAccess nameAccess = (XNameAccess)OODatabaseContext;
                object datasource = nameAccess.getByName(datasourceName);
                XNamingService namingservice = (XNamingService)OODatabaseContext;
                namingservice.revokeObject(datasourceName);
                */

                //attempt 2
                string databaseLocation = databaseRegistrations.getDatabaseLocation(datasourceName);
                databaseRegistrations.revokeDatabaseLocation(datasourceName);

                if (!String.IsNullOrEmpty(databaseLocation))
                    try
                    {                             
                        //As File Path converts the uno file string into a standard form i.e. "file:///c:/temp/DatabaseFile.odb" to "c:\\temp\\DatabaseFile.odb"
                        File.Delete(databaseLocation.AsFilepath());                                 
                    }
                    catch (System.Exception ex)
                    { 
                        //some error handling
                    }
            }
            return result;
        }
        catch (System.Exception ex)
        {
            //More error handling
        }
    }

Any ideas how I can unregister this datasource such that I can then delete the odb. Thanks


Solution

  • Managed to get around this issue and just in case anyone else is interested here's how.
    The key was to get a reference to the actual datasource and to then dispose of this.

    The basic steps are:

    1. Check if a datasource exists with the specified name
    2. Get datasource object
    3. Get the datasource filename
    4. Dispose of the database document associated with the datasource
    5. Dispose the actual datasource
    6. Delete the database file :)

    The source code for this looks something like

    XNameAccess nameAccess = (XNameAccess)_MultiServiceFactory.createInstance("com.sun.star.sdb.DatabaseContext");
    object datasource = nameAccess.getByName(datasourceName);
    XDocumentDataSource obj = (XDocumentDataSource)((Any)datasource).Value;
    //get the location of the associated odb file before we dispose the document object
    //and deregister the datasource
    string databaseLocation = databaseRegistrations.getDatabaseLocation(datasourceName);
    databaseRegistrations.revokeDatabaseLocation(datasourceName);
    ((XComponent)obj.DatabaseDocument).dispose();
    ((XComponent)obj).dispose();
    
    
    //put in a try block as we want to continue even if this fails
    //AsFilepath converts the OpenOffice file path to standard for that can be used with the standard IO file access classes
    File.Delete(databaseLocation.AsFilepath()); 
    

    If there are any improvements please let me know...