尝试打开IE 10/11时,ESENT始终抛出EsentPageSizeMismatchException WebCache.dat

时间:2016-07-11 17:26:34

标签: .net powershell internet-explorer esent

我正在尝试创建一个powershell脚本来读取IE 10/11互联网历史记录,该历史记录存储在AppData \ Local \ Microsoft \ Windows \ WebCache \ WebCache.dat中。

我正在使用Managed Esent + - 与.NET中的Win32 Jet API进行交互。

我的问题是我永远无法实际打开数据库,因为当我调用JetAttachDatabase时会抛出EsentPageSizeMismatchException。在对此错误进行一些研究后,我发现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 个答案:

答案 0 :(得分:0)

如果您注意到,在一种情况下,JetAttachDatabase失败并且异常失败,而JetInit则失败。

您确实需要设置DatabasePageSize。 JetInit实际上是一个糟糕的名字。应该称之为JetInitAndReplayLogFiles。它将查看日志目录中的事务日志文件(edb * .log的默认名称)(默认值:"。"),并重放事务日志文件中的操作。

您现在可能正在接收使用不同页面大小创建的其他事务日志文件。理论:您在第一次尝试时无意中创建了edb*.log个文件。

一些可能的解决方案:

-cd首先包含日志文件的目录。

- 更改LogFileDirectory(您可以将JetSetSystemParameterJET_param.LogFilePath一起使用,也可以使用包装类InstanceParameters.LogFileDirectory)。哦,你还需要将InstanceParameters.BaseName设置为" v01",因为这是webcache01.dat文件似乎使用的内容(影响&#34的名称; edb.log" vs" v01.log")。

- 使用esentutl.exe -r v01使数据库进入“干净关闭”状态。状态,然后将InstanceParameters.Recovery设置为false,以避免意外创建新的事务日志文件。而且我发现你已经附上了AttacheDatabaseGrbit.ReadOnly

最后,我希望这只是为了好奇。工作在inetcache上的人可以随时更改实现细节。如果用于法医目的,微软确实协助执法机构进行法医工作。

-Martin

答案 1 :(得分:0)

您应该使用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);

答案 2 :(得分:0)

对于我的情况,我必须手动进入bin / Debug文件夹并在每次切换数据库之前手动删除内容,然后再次调试它。我希望这可以帮助那些面临这个问题的人。