Select layer by location puts persistent lock on underlying shapefile

1892
2
01-13-2011 08:41 AM
ErikaDade
New Contributor III
Hi all,

When using the Geoprocessor, making a layer from a shapefile and then making a selection in the layer by location results in a persistent lock file associated with the original shapefile.  If I do selection by attribute instead then the lock file will go away when the internal layer and shapefile are deleted.  ArcMap has to be closed to run the geoprocessing operation more than once because the lock file persists.  I have posted on this before for 9.2/9.3 in reference to multiple geoprocessing runs within a single ArcMap session.  With the release of 10.0, the new lock files allowed me to further trace the problem.    Any ideas on how to clean up would be great!

Test function follows.


HRESULT CVectorizationDlg::GPtest()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr;

::CoInitialize(NULL);  // Before any ArcObjects AND  must scope what follows before AoUninitialize()
{
  IGeoProcessor2Ptr ipGP(CLSID_GeoProcessor);
  IGeoProcessorResultPtr ipResult;
  CComBSTR bsMessages;
  CString cMsg;

  // Don't add temp layers to map document
  VARIANT_BOOL bOut;
  bOut = FALSE;
  //bOut = TRUE;
  hr = ipGP->put_AddOutputsToMap(bOut);

  // Do overwrite temp layers on disk
  VARIANT_BOOL bOverwrite;
  bOverwrite = TRUE;
  hr = ipGP->put_OverwriteOutput(bOverwrite);

  // Temp map layers
  VARIANT_BOOL bTempMapLayers;
  bTempMapLayers = TRUE;
  hr = ipGP->put_TemporaryMapLayers(bTempMapLayers);

  // Singleton object!!!
  IGPUtilitiesPtr ipGPUtil(CLSID_GPUtilities);

  // Get scratch working directory
  CString sTempDir = "c:\\temp\\arcsie\\erikadade\\vector\\";  // A directory that you can delete
  sTempDir = TempDir();  // This creates it on a local preferred path if it doesn't exist
  if (sTempDir == "") return E_FAIL;

  CComBSTR bOldWorkPath;
  CComBSTR bTempDir(sTempDir);
  hr = ipGPUtil->get_Workspace(&bOldWorkPath);
  hr = ipGPUtil->put_Workspace(bTempDir);
  hr = ipGPUtil->put_RefreshCatalogParent(-1);

  // Keep track of all layers/files added so we can delete them at the end
  std::vector<CString> vShapefileList;
  int nShape = 0;

  // Build the array of variant paramters
  IVariantArrayPtr ipValues(CLSID_VarArray);
  
  // COPY FEATURES  --  to a temp shapefile

  CString sIn = "C:\\users\\erika dade\\arcgis\\xunarc10.0\\vectors\\v.shp";  // Any old feature shapefile
  vShapefileList.push_back(sTempDir + "copy.shp");

  hr = ipValues.CreateInstance(CLSID_VarArray);
  hr = ipValues->Add(_variant_t(sIn)); // Input Feature Class
  hr = ipValues->Add(_variant_t("copy.shp")); // Output Feature Class

  ipResult.CreateInstance(CLSID_GeoProcessorResult);
  hr = ipGP->Execute(L"CopyFeatures_management", ipValues, 0, &ipResult);

  if (FAILED(hr)) {
   ipResult->GetMessages(0, &bsMessages);  cMsg = bsMessages;
   MessageBox(cMsg, "Vectorization (GP-test1)", MB_OK);::SysFreeString(bsMessages);
   ipResult = 0; ipGP = 0;
   return hr;
  }

  //  MAKE LAYER  -- this creates lock file on copy shapefile in temp directory

   hr = ipValues.CreateInstance(CLSID_VarArray);
  hr = ipValues->Add(_variant_t("copy.shp")); // Input Feature Class
  hr = ipValues->Add(_variant_t(L"copyL")); // Output Feature Layer
  vShapefileList.push_back("copyL");

  ipResult.CreateInstance(CLSID_GeoProcessorResult);
  hr = ipGP->Execute(L"MakeFeatureLayer_management", ipValues, 0, &ipResult);

  if (FAILED(hr)) {
   ipResult->GetMessages(0, &bsMessages);  cMsg = bsMessages;
   MessageBox(cMsg, "Vectorization (GP-test2)", MB_OK);::SysFreeString(bsMessages);
   ipResult = 0; ipGP = 0;
   return hr;
  }

  //  SELECT INTERSECTION 
  // -- do this BY LOCATION and it will not release lock file on shapefile

  if (MessageBox("Set another lock through SelectLayerByLOCATION?", "GP Test", MB_YESNO) == IDYES)
  {
   CString outerPoly = "C:\\users\\erika dade\\arcgis\\xunarc10.0\\vectors\\vOuter.shp";  // boundary of feature shapefile
   hr = ipValues.CreateInstance(CLSID_VarArray);
   hr = ipValues->Add(_variant_t(L"copyL"));  // Input feature layer
   hr = ipValues->Add(_variant_t(L"SHARE_A_LINE_SEGMENT_WITH")); // No tol, NEW SELECTION
   hr = ipValues->Add(_variant_t(outerPoly)); // Intersect feature class
   hr = ipResult.CreateInstance(CLSID_GeoProcessorResult);
   hr = ipGP->Execute(L"SelectLayerByLocation_management", ipValues, 0, &ipResult);  // This puts another? lock on shapefile "copy" !!!

   if (FAILED(hr)) {
    ipResult->GetMessages(0, &bsMessages);
    cMsg = bsMessages;
    MessageBox(cMsg, "Vectorization (GP-test3)", MB_OK);::SysFreeString(bsMessages);
    ipResult = 0; ipGP = 0;
    return hr;
   }
  }

  // -- do this BY ATTRIBUTE and it WILL release lock file on shapefile
  if (MessageBox("Set another lock through SelectLayerByATTRIBUTE?", "GP Test", MB_YESNO) == IDYES)
  {
   CString sSelect;
   sSelect.Format("\"ID\" <> -9999");

   hr = ipValues.CreateInstance(CLSID_VarArray);
   hr = ipValues->Add(_variant_t(L"copyL")); // Input Feature Layer
   hr = ipValues->Add(_variant_t(L"NEW_SELECTION")); // Exclusive new selection
   hr = ipValues->Add(_variant_t(sSelect));  // SQL

   ipResult.CreateInstance(CLSID_GeoProcessorResult);
   hr = ipGP->Execute(L"SelectLayerByAttribute_management", ipValues, 0, &ipResult);

   if (FAILED(hr)) {
    ipResult->GetMessages(0, &bsMessages);  cMsg = bsMessages;
    MessageBox(cMsg, "Vectorization (GP-test4)", MB_OK);::SysFreeString(bsMessages);
    ipResult = 0; ipGP = 0;
    return hr;
   }
  }

  //===================================================
  //  Tidy up   
  //===================================================
  ipResult = 0;

  // If you leave the temp shape files (with .LOCK file) then can overwrite successfully.
  // If delete the temp shape files (but not .LOCK file) then cannot write new shapefile by same name

  bool bDeleteTemp = true;
  if (MessageBox("Delete temp files/layers/dir?", "GP Test", MB_YESNO) == IDNO) bDeleteTemp = false;
  if (bDeleteTemp) {
   bool bDel = false;
   for (int i=0; i<vShapefileList.size(); i++) {
    CString name(vShapefileList.at(i));
    CString layerName = dropFileSuffix(extractFileName(name));
    CComBSTR bLayerName(layerName);
    hr = ipGPUtil->RemoveInternalLayer(bLayerName);
    bLayerName.Empty();
    bDel = DeleteGPTempFile(name);
   }
  }
  vShapefileList.clear();

  // Both of these things necessary for multiple geoprocessor runs
  hr = ipGPUtil->ReleaseInternals();  // Critical !!!    11/2008

  hr = ipGPUtil->put_RefreshCatalogParent(-1);
  hr = ipGPUtil->put_Workspace(bOldWorkPath); 

  ipValues = 0;
  ipResult = 0;
  ipGPUtil = 0;
  ipGP = 0;

  // Will need to delete temp directory for client
  //if (bDeleteTemp) DeleteFolder(sTempDir);

}

// Uninitialize COM
::CoUninitialize();

return hr;
}
0 Kudos
2 Replies
ChrisSnyder
Regular Contributor III
Try deleteing the feature layer (the one(s) that reference the shapefile).

Use the Delete_managment geoprocessing tool.
0 Kudos
ErikaDade
New Contributor III
Thanks very much for your response, but sadly Delete_management does not do the trick.  When SelectLayerByLocation is used, the lock file persists.  Also, tried clearing the selection with SelectLayerByAttribute after selecting by location.  No effect either.
0 Kudos