Introduction
This is an easy one. This article will just save you a few clicks and scrolls reading the MSDN guide.
I have encountered a need to get the filename of the MS Access file opened. My class already has a session object as a member. I thought I could add a setFilename()
function. But no! Being the lazy programmer, I don't want to do that to my already-tidy clean class; and doing so will require changing all other classes to pass the filename in the chain. The solution: get the filename from the session object.
This article shows how.
Method
- There is a rowset member object of a session. From that rowset, get the
DataSource
interface. CComPtr spGetDataSource;
HRESULT hr = r_session.m_spOpenRowset->QueryInterface(
IID_IGetDataSource, (void**)&spGetDataSource);
-
Get the DBProperties
interface from the DataSource
object
CComPtr spProperties;
hr = spGetDataSource->GetDataSource(IID_IDBProperties,
(IUnknown **)&spProperties);
- Finally, get the data source property you want. For example, get the filename (
DBPROP_DATASOURCENAME
): CDBPropIDSet set(DBPROPSET_DATASOURCEINFO);
set.AddPropertyID(DBPROP_DATASOURCENAME);
DBPROPSET* pPropSet = NULL;
ULONG ulPropSet = 0;
hr = spProperties->GetProperties(1, &set, &ulPropSet, &pPropSet);
if (FAILED(hr))
return hr;
printf(_T("filename = %s\n"), (_bstr_t)(_variant_t)
pPropSet->rgProperties[0].vValue);
Using the code
The file DataSourceInfo.cpp contains the following function which you can use to retreive any data source information.
HRESULT hr_GetDataSourceInfo(CSession & r_session, DWORD dw_infoCode,
_variant_t & r_info)
{
HRESULT hr = S_OK;
try
{
CComPtr spGetDataSource;
HRESULT hr = r_session.m_spOpenRowset->QueryInterface(
IID_IGetDataSource, (void**)&spGetDataSource);
CComPtr spProperties;
hr = spGetDataSource->GetDataSource(IID_IDBProperties,
(IUnknown **)&spProperties);
CDBPropIDSet set(DBPROPSET_DATASOURCEINFO);
set.AddPropertyID(dw_infoCode);
DBPROPSET* pPropSet = NULL;
ULONG ulPropSet = 0;
hr = spProperties->GetProperties(1, &set, &ulPropSet, &pPropSet);
if (FAILED(hr))
{
return hr;
}
ATLASSERT(ulPropSet == 1);
VariantCopy(&r_info, &pPropSet->rgProperties[0].vValue);
CoTaskMemFree(pPropSet->rgProperties);
CoTaskMemFree(pPropSet);
}
catch (...)
{
}
return hr;
}
You will need to pass the session, the data source information property code and a variant that will receive the information.
A list of the data source information properties can be found at the MSDN site.
Conclusion
Finally, may I say - the codes here were written while I'm cooking my dinner :-). I't may not be perfect, but I hope it helped to illustrate my points.