在C#中解析WebCacheV01.dat

时间:2017-01-27 14:45:04

标签: c# parsing esent

我希望使用C#解析WebCacheV01.dat文件,以便在Internet浏览器中找到上传的最后一个文件位置。

  

%LOCALAPPDATA%\微软\的Windows \的WebCache \ WebCacheV01.dat

我使用Managed Esent nuget包。

  • Esent.Isam
  • Esent.Interop

当我尝试运行以下代码时,它失败了:

Api.JetGetDatabaseFileInfo(filePath, out pageSize, JET_DbInfo.PageSize);

或者如果我使用

Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.CircularLog, 1, null);

Api.JetAttachDatabase(sesid, filePath, AttachDatabaseGrbit.ReadOnly);

我收到以下错误:

  

未处理的类型异常   发生了'Microsoft.Isam.Esent.Interop.EsentFileAccessDeniedException'   在Esent.Interop.dll

     

其他信息:无法访问文件,文件被锁定或正在使用

string localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string filePathExtra = @"\Microsoft\Windows\WebCache\WebCacheV01.dat";
string filePath = string.Format("{0}{1}", localAppDataPath, filePathExtra);

JET_INSTANCE instance;
JET_SESID sesid;
JET_DBID dbid;
JET_TABLEID tableid;
String connect = "";

JET_SNP snp;
JET_SNT snt;
object data;
int numInstance = 0;
JET_INSTANCE_INFO [] instances;
int pageSize;

JET_COLUMNDEF columndef = new JET_COLUMNDEF();
JET_COLUMNID columnid;

Api.JetCreateInstance(out instance, "instance");
Api.JetGetDatabaseFileInfo(filePath, out pageSize, JET_DbInfo.PageSize);
Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, JET_param.DatabasePageSize, pageSize, null);
//Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.CircularLog, 1, null);

Api.JetInit(ref instance);
Api.JetBeginSession(instance, out sesid, null, null);

//Do stuff in db

Api.JetEndSession(sesid, EndSessionGrbit.None);
Api.JetTerm(instance);

如果不进行修改,是否无法阅读?

查看器

http://www.nirsoft.net/utils/ese_database_view.html

的Python

https://jon.glass/attempts-to-parse-webcachev01-dat/

3 个答案:

答案 0 :(得分:1)

我无法得到亚当的工作答案。对我有用的是使用AlphaVSS(一个.NET类库,具有用于卷影复制服务的托管API的副本)进行复制。该文件处于“脏关机”状态,因此我另外编写了此文件来处理打开它时引发的异常:

catch (EsentErrorException ex)
{   // Usually after the database is copied, it's in Dirty Shutdown state
    // This can be verified by running "esentutl.exe /Mh WebCacheV01.dat"
    logger.Info(ex.Message);
    switch (ex.Error)
    {
        case JET_err.SecondaryIndexCorrupted:
            logger.Info("Secondary Index Corrupted detected, exiting...");
            Api.JetTerm2(instance, TermGrbit.Complete);
            return false;
        case JET_err.DatabaseDirtyShutdown:
            logger.Info("Dirty shutdown detected, attempting to recover...");
            try
            {
                Api.JetTerm2(instance, TermGrbit.Complete);
                Process.Start("esentutl.exe", "/p /o " + newPath);
                Thread.Sleep(5000);
                Api.JetInit(ref instance);
                Api.JetBeginSession(instance, out sessionId, null, null);
                Api.JetAttachDatabase(sessionId, newPath, AttachDatabaseGrbit.None);
            }
            catch (Exception e2)
            {
                logger.Info("Could not recover database " + newPath + ", will try opening it one last time. If that doesn't work, try using other esentutl commands", e2);
            }
            break;
    }
}

答案 1 :(得分:0)

问题:

该文件可能正在使用中。

解决方案:

要释放锁定的文件,请停止计划任务 - \ Microsoft \ Windows \ Wininet \ CacheTask

守则

    public override IEnumerable<string> GetBrowsingHistoryUrls(FileInfo fileInfo)
            {
                var fileName = fileInfo.FullName;
                var results = new List<string>();
                try
                {
                    int pageSize;
                    Api.JetGetDatabaseFileInfo(fileName, out pageSize, JET_DbInfo.PageSize);
                    SystemParameters.DatabasePageSize = pageSize;

                    using (var instance = new Instance("Browsing History"))
                    {
                        var param = new InstanceParameters(instance);
                        param.Recovery = false;
                        instance.Init();
                        using (var session = new Session(instance))
                        {
                            Api.JetAttachDatabase(session, fileName, AttachDatabaseGrbit.ReadOnly);
                            JET_DBID dbid;
                            Api.JetOpenDatabase(session, fileName, null, out dbid, OpenDatabaseGrbit.ReadOnly);

                            using (var tableContainers = new Table(session, dbid, "Containers", OpenTableGrbit.ReadOnly))
                            {
                                IDictionary<string, JET_COLUMNID> containerColumns = Api.GetColumnDictionary(session, tableContainers);

                                if (Api.TryMoveFirst(session, tableContainers))
                                {
                                    do
                                    {
                                        var retrieveColumnAsInt32 = Api.RetrieveColumnAsInt32(session, tableContainers, columnIds["ContainerId"]);
                                        if (retrieveColumnAsInt32 != null)
                                        {
                                            var containerId = (int)retrieveColumnAsInt32;
                                            using (var table = new Table(session, dbid, "Container_" + containerId, OpenTableGrbit.ReadOnly))
                                            {
                                                var tableColumns = Api.GetColumnDictionary(session, table);
                                                if (Api.TryMoveFirst(session, table))
                                                {
                                                    do
                                                    {

                                                        var url = Api.RetrieveColumnAsString(
                                                            session,
                                                            table,
                                                            tableColumns["Url"],
                                                            Encoding.Unicode);

                                                        var downloadedFileName = Api.RetrieveColumnAsString(
                                                        session,
                                                        table,
                                                        columnIds2["Filename"]);

                                                        if(string.IsNullOrEmpty(downloadedFileName))  // check for download history only.
                                                             continue;

                                                        // Order by access Time to find the last uploaded file.                                                     
                                                        var accessedTime = Api.RetrieveColumnAsInt64(
                                                        session,
                                                        table,
                                                        columnIds2["AccessedTime"]);
                                                        var lastVisitTime = accessedTime.HasValue ? DateTime.FromFileTimeUtc(accessedTime.Value) : DateTime.MinValue;


                                                        results.Add(url);

                                                    }
                                                    while (Api.TryMoveNext(session, table.JetTableid));
                                                }
                                            }
                                        }
                                    } while (Api.TryMoveNext(session, tableContainers));
                                }
                            }
                        }
                    }

                }
                catch (Exception ex)
                {
                    // log goes here....
                }

                return results;
            }

的Utils

任务计划程序包装器

您可以使用Microsoft.Win32.TaskScheduler.TaskService Wrapper使用c#停止它,只需添加此Nuget包[nuget]:https://taskscheduler.codeplex.com/

用法

public static FileInfo CopyLockedFileRtl(DirectoryInfo directory, FileInfo fileInfo, string remoteEndPoint)
        {
            FileInfo copiedFileInfo = null;
            using (var ts = new TaskService(string.Format(@"\\{0}", remoteEndPoint)))
            {
                var task = ts.GetTask(@"\Microsoft\Windows\Wininet\CacheTask");
                task.Stop();
                task.Enabled = false;
                var byteArray = FileHelper.ReadOnlyAllBytes(fileInfo);
                var filePath = Path.Combine(directory.FullName, "unlockedfile.dat");
                File.WriteAllBytes(filePath, byteArray);
                copiedFileInfo = new FileInfo(filePath);
                task.Enabled = true;
                task.Run();
                task.Dispose();
            }

            return copiedFileInfo;
        }

答案 2 :(得分:-1)

我正在考虑使用&#39;最近的项目&#39;选择要上传条目的文件时的文件夹写在此处:

  

C:\用户\ USER \应用程序数据\漫游\微软\的Windows \最近

string recent = (Environment.GetFolderPath(Environment.SpecialFolder.Recent));