ArcObjects ExcelWorkspaceFactory Won't Release Excel File

462 views Asked by At

I'm working with ArcObjects to set up a batch import from xls and csv files into a geodatabase. That part works fine, but after the import, I want to delete the file. This, however, doesn't work, because the file is still open. None of the interfaces being used descend from IDisposable or expose a Close method. I've also tried using a ComReleaser to force close all of the COM objects that I open, but that doesn't work either. The only things I've seen pertaining to closing a connection say that I need to remove all references to these types and force garbage collection, which is against standards (for good reason).

Here's the method I'm using for the excel import:

private ServiceResult<IEnumerable<int>> InsertControlsFromXls(FileInfo xlsFile) {
  ServiceResult<IEnumerable<int>> result = new ServiceResult<IEnumerable<int>>();


  using(ComReleaser comReleaser = new ComReleaser()) {

    //read in the spreadsheet as a workspace
    Type factoryType = Type.GetTypeFromProgID("esriDataSourcesOleDB.ExcelWorkspaceFactory");
    IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);

    IWorkspace workspace = workspaceFactory.OpenFromFile(xlsFile.FullName, 0);
    IFeatureWorkspace remoteWorkspace = (IFeatureWorkspace)OpenWorkspace();
    IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
    IWorkspaceEdit2 session = (IWorkspaceEdit2)remoteWorkspace;
    IMultiuserWorkspaceEdit multiuserWorkspace = (IMultiuserWorkspaceEdit)remoteWorkspace;

    comReleaser.ManageLifetime(workspaceFactory);
    comReleaser.ManageLifetime(workspace);
    comReleaser.ManageLifetime(remoteWorkspace);
    comReleaser.ManageLifetime(featureWorkspace);
    comReleaser.ManageLifetime(session);
    comReleaser.ManageLifetime(multiuserWorkspace);

    try {
      //session.StartEditing(false);
      multiuserWorkspace.StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMVersioned);
      session.StartEditOperation();

      Match tableMatch = _tableRecReg.Match(xlsFile.Name);
      string tableName = tableMatch.Success ? tableMatch.Groups[1].Value + "$" : "Sheet1$";

      ITable table = featureWorkspace.OpenTable(tableName);

      result.Value = CopyAllFeatures(table, remoteWorkspace.OpenFeatureClass(AppSettings.DefaultSchema + "." + ControlMap.TableName));

      session.StopEditOperation();
      session.StopEditing(true);

    } catch {
      session.AbortEditOperation();
      session.StopEditing(false);
      throw;
    }
  }

  return result;
}
2

There are 2 answers

0
Ixonal On BEST ANSWER

Ok, I got it to work by going hog-wild with ComReleaser objects. Basically, I scanned through my code, and anytime I found anything that was at all from ArcObjects, I attached a ComReleaser to manage it. Basically, I'm just doing manual memory management. At any rate, it does seem to release the file, so long as EVERYTHING is released (even if it doesn't seem relevant). As stated in comments above, the ComReleaser class should use ReleaseComObject under the hood, so that path should work as well.

0
Daniel On

I would guess in your sample it was the ITable that was causing it. The table object will lock the sheet. At least, it does this in other geodatabases.

Not sure what the CopyAllFeatures does, but also keep an eye out for ICursor.