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;
}