我正在尝试读取一些现有的和未安装的 ESE 数据库文件。我已经相当成功地使用了一个 .dat 文件。但是,当我尝试打开 PageSize 等于 32768 的现有数据库时,出现错误。
这是我的代码(没有错误处理):
FError := JetSetSystemParameter(&FInstance, nil, JET_paramRecovery, FPagesize, "off");
FError := JetCreateInstance(&FInstance, 'myinstance');
FError := JetInit(&FInstance);
FError := JetBeginSession(FInstance, &FSessionId, nil, nil);
FError := JetAttachDatabase(FSessionId, FFilename, JET_bitDbReadOnly);
在 JetAttachDatabase 调用时失败,返回 -1213 代码。我是不是做错了什么?
我运行的是 Windows 7 32 位。
Esent 引擎默认使用一定的页面大小。如果我没记错的话是4K。您必须告诉引擎您要打开的数据库具有不同的页面大小。使用类似的东西:
FError := JetSetSystemParameter(&FInstance, nil, JET_paramDatabasePageSize, 32768, nil);
如果您一直打开不同的数据库,您可能希望自动检查应用程序并设置页面大小。
ESE 中的老问题,但仍然令人头疼。
对于您尝试打开的数据库,您必须首先获取页面大小,然后在发出 JetCreaeInstance 调用之前通过“JET_paramDatabasePageSize”参数指定该大小。 这是我在 WRL 中编写的一些代码(请原谅路径字符串中的 WinRT 内容,但您明白了):
HRESULT SetInstancePageSize(_In_ HSTRING const hstrPath) noexcept
{ HRESULT hr;
if (hstrPath != nullptr)
{
/* This may NOT be called after JetInit/JetCreateInstance */
if (m_hEseInstance == JET_instanceNil)
{ uint32_t cwchPath = 0;
const wchar_t* const pcwszFilePath = ::WindowsGetStringRawBuffer(hstrPath, &cwchPath);
if (cwchPath > 0 && *pcwszFilePath != L'\0' && cwchPath <= MAX_PATH)
{ unsigned long ulPageSize = 0;
JET_ERR rc = ::JetGetDatabaseFileInfo(pcwszFilePath, &ulPageSize, sizeof(ulPageSize), JET_DbInfoPageSize);
if (rc == JET_errSuccess)
rc = ::JetSetSystemParameter(nullptr, JET_sesidNil, JET_paramDatabasePageSize, ulPageSize, nullptr);
hr = HRESULT_FROM_JETERR(rc);
}
else
hr = WRLESE_E_INVALIDPATH;
}
else
hr = WRLESE_E_CANNOTBESETNOW;
}
else
hr = WRLESE_E_STRINGISNULL;
return hr;
}