ESENT всегда выдает EsentPageSizeMismatchException при попытке открыть IE 10/11 WebCache.dat
Я пытаюсь создать сценарий powershell для чтения интернет-истории IE 10/11, которая хранится в AppData\Local\Microsoft\Windows\WebCache\WebCache.dat.
Я использую Managed Esent+ - для взаимодействия с Win32 Jet API в.NET.
Моя проблема в том, что я никогда не смогу открыть базу данных, так как EsentPageSizeMismatchException выбрасывается, когда я вызываю JetAttachDatabase. Проведя некоторые исследования этой ошибки, я обнаружил, что IE WebCache имеет размер страницы 32K. Когда я попытался исправить это, установив системный параметр DatabasePageSize в 0x8000, JetInit начал выдавать то же исключение.
Вот код, который у меня есть
#stop the things locking the database
stop-process -name taskhost
stop-process -name dllhost
#give powershell access to the interop dlls
add-type -path "$PSScriptRoot\ManagedEsent 1.6\Esent.Interop.dll"
$instance = [Microsoft.Isam.Esent.Interop.JET_INSTANCE]::Nil
#set page size
[Microsoft.Isam.Esent.Interop.api]::JetSetSystemParameter(
$instance,
[Microsoft.Isam.Esent.Interop.JET_SESID]::Nil,
[Microsoft.Isam.Esent.Interop.JET_param]::DatabasePageSize,
0x8000,
$null
)
[Microsoft.Isam.Esent.Interop.Api]::JetCreateInstance([ref]$instance,"testing")
# init the instance, throws EsentPageSizeMismatchException if the page size is not default
[Microsoft.Isam.Esent.Interop.Api]::JetInit([ref]$instance)
$sesid = [Microsoft.Isam.Esent.Interop.JET_SESID]::Nil
[Microsoft.Isam.Esent.Interop.Api]::JetBeginSession($instance,[ref]$sesid,$null,$null)
# throws EsentPageSizeMismatchException if page size is default
[Microsoft.Isam.Esent.Interop.api]::JetAttachDatabase(
$sesid,
"C:\Users\Administrator\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat",
[Microsoft.Isam.Esent.Interop.AttachDatabaseGrbit]::ReadOnly
)
...
Похоже, что движку ESENT не нравится иметь размер страницы не по умолчанию, но я искал в Интернете, и, похоже, нет способа изменить размер страницы движка. Что вызывает эту ошибку?
3 ответа
Если вы заметили, в одном случае это JetAttachDatabase
что терпит неудачу с исключением, и JetInit
в другом.
Вы действительно правы, что вам нужно установить DatabasePageSize.JetInit
на самом деле плохое имя. Это надо называть как то JetInitAndReplayLogFiles
, Он будет просматривать файлы журнала транзакций (имя по умолчанию edb*.log) в каталоге журналов (по умолчанию: ".") И воспроизводит операции в файлах журнала транзакций.
Вы, вероятно, теперь выбираете другие файлы журнала транзакций, созданные с другим размером страницы. Теория: вы подбираете edb*.log
файлы, которые вы случайно создали при первой попытке.
Некоторые потенциальные решения:
-cd в каталог, который сначала содержит файлы журнала.
-Измените LogFileDirectory (вы можете использовать JetSetSystemParameter
с JET_param.LogFilePath
или класс оболочки InstanceParameters.LogFileDirectory
). О, вам также нужно установить InstanceParameters.BaseName
на "v01", поскольку именно это, похоже, использует файл webcache01.dat (влияет на имена "edb.log" против "v01.log").
-Использование esentutl.exe -r v01
чтобы привести базу данных в состояние "чистого отключения", а затем установить InstanceParameters.Recovery
в false
чтобы случайно не создавать новые файлы журнала транзакций. И я вижу, что вы уже привязаны к AttacheDatabaseGrbit.ReadOnly
,
Наконец, я надеюсь, что это просто для любопытства. Люди, которые работали с inetcache, могут изменить детали реализации в любое время. Если это для судебных целей, Microsoft действительно помогает судебным усилиям правоохранительных органов.
-Мартин
Вы должны использовать JetGetDatabaseFileInfo(), чтобы получить требуемый размер страницы для использования с SetSetSystemParameter()
Вот пример в C# (эй... это достаточно близко, верно?)
int pageSize;
JET_INSTANCE instance;
JET_SESID sesId;
// match the Page size
Api.JetGetDatabaseFileInfo(databasePath, out pageSize, JET_DbInfo.PageSize);
Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, JET_param.DatabasePageSize, pageSize, null);
В моем случае мне пришлось вручную зайти в папку bin/Debug и вручную удалять содержимое каждый раз, когда я переключал базы данных, прежде чем снова отлаживать его. Я надеюсь, что это помогает кому-то, кто сталкивается с этой проблемой.