为了账号安全,请及时绑定邮箱和手机立即绑定

如何打开 Thumbscache.db

如何打开 Thumbscache.db

C#
倚天杖 2022-10-15 15:19:34
我正在尝试打开 thumbscache.db 文件,我尝试像打开任何其他数据库一样打开它,但没有用。我还在 C# 中寻找任何 API 或支持。请建议是否有其他方法。顺便说一句,下面是我到目前为止的方法。1. 像任何其他数据库一样打开它。        path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);        path += @"\Microsoft\Windows\Explorer\thumbcache_1280.db";        datasource = "Data source = " + path;        SQLiteCommand cmd = new SQLiteCommand();        SQLiteConnection conn = new SQLiteConnection(datasource);        cmd.Connection = conn;        cmd.CommandText = "SELECT * FROM Filename";        conn.Open();        SQLiteDataAdapter sqda = new SQLiteDataAdapter(cmd);        DataTable dt = new DataTable();        sqda.Fill(dt);        dataGridView1.DataSource = dt;        conn.Close();但是出现了这个异常。2.使用ShellFile打开它        ShellFile shellFile = ShellFile.FromFilePath(path);         Bitmap bitmap = shellFile.Thumbnail.ExtraLargeBitmap;         pbThumbs.Image = bitmap;而不是 thumbscache 它提供文件拇指图标。3. 使用 OpenMcdf 作为 OLE 文档打开        path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);        path += @"\Microsoft\Windows\Explorer\thumbcache_1280.db";        CompoundFile cf = new CompoundFile(path);        CFStream foundStream = cf.RootStorage.GetStream("Filename");        byte[] temp = foundStream.GetData();这个异常出现了。
查看完整描述

1 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

以下是用于打开 thumbcache*.db 文件的 C# 类。


public class ThumbCache

{


    private const int WindowsVista = 0x14;

    private const int Windows7 = 0x15;

    private const int Windows8 = 0x1A;

    private const int Windows8v2 = 0x1C;

    private const int Windows8v3 = 0x1E;

    private const int Windows8_1 = 0x1F;

    private const int Windows10 = 0x20;


    private Stream stream;

    private uint fileVersion;


    private byte[] tempBytes = new byte[65536];

    private uint[] entryOffsets;


    public int ImageCount { get { return entryOffsets.Length; } }


    public ThumbCache(string fileName)

    {

        stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        ReadFromStream(stream);

    }


    public ThumbCache(Stream stream)

    {

        ReadFromStream(stream);

    }


    ~ThumbCache()

    {

        stream.Close();

    }


    private void ReadFromStream(Stream stream)

    {

        stream.Read(tempBytes, 0, 32);


        string magic = Encoding.ASCII.GetString(tempBytes, 0, 4);

        if (!magic.Equals("CMMM"))

            throw new ApplicationException("This is not a valid ThumbCache file.");


        fileVersion = BitConverter.ToUInt32(tempBytes, 4);

        uint fileType = BitConverter.ToUInt32(tempBytes, 8);


        uint firstEntryPtr = 0;

        uint availableEntryPtr = 0;

        if (fileVersion < Windows8v2)

        {

            firstEntryPtr = BitConverter.ToUInt32(tempBytes, 12);

            availableEntryPtr = BitConverter.ToUInt32(tempBytes, 16);

        }

        else

        {

            firstEntryPtr = BitConverter.ToUInt32(tempBytes, 16);

            availableEntryPtr = BitConverter.ToUInt32(tempBytes, 20);

        }


        stream.Seek(firstEntryPtr, SeekOrigin.Begin);


        List<uint> entryOffsetList = new List<uint>();


        try

        {

            uint entrySize;

            while (stream.Position < stream.Length)

            {

                entryOffsetList.Add((uint)stream.Position);


                stream.Read(tempBytes, 0, 8);

                if ((tempBytes[0] != 'C') || (tempBytes[1] != 'M') || (tempBytes[2] != 'M') || (tempBytes[3] != 'M'))

                    break;


                entrySize = BitConverter.ToUInt32(tempBytes, 4);

                stream.Seek(entrySize - 8, SeekOrigin.Current);

            }

        }

        catch { }


        entryOffsets = entryOffsetList.ToArray();

    }


    public ThumbInfo GetImage(int imageIndex, bool needImage)

    {

        if (entryOffsets.Length == 0) return null;

        if ((imageIndex < 0) || (imageIndex >= entryOffsets.Length)) return null;

        return new ThumbInfo(stream, entryOffsets[imageIndex], tempBytes, fileVersion, needImage);

    }


    public Dictionary<string, string> GetMetadata(ThumbInfo info)

    {

        var dict = new Dictionary<string, string>();

        if (entryOffsets.Length == 0) return dict;

        if (info == null) return dict;


        dict.Add("File offset", info.fileOffset.ToString());

        dict.Add("Entry size", info.entrySize.ToString());

        dict.Add("Entry hash", info.entryHash.ToString("X16"));

        dict.Add("Filename length", info.fileNameLength.ToString());

        dict.Add("Padding length", info.paddingLength.ToString());

        dict.Add("Data length", info.dataLength.ToString());

        dict.Add("Image width", info.imageWidth.ToString());

        dict.Add("Image height", info.imageHeight.ToString());

        dict.Add("Data checksum", info.dataChecksum.ToString("X16"));

        dict.Add("Header checksum", info.headerChecksum.ToString("X16"));

        return dict;

    }



    public class ThumbInfo

    {

        public Image image;

        public long fileOffset;

        public uint entrySize;

        public ulong entryHash;

        public uint fileNameLength;

        public uint paddingLength;

        public uint dataLength;

        public ulong dataChecksum;

        public ulong headerChecksum;

        public uint imageWidth;

        public uint imageHeight;


        public ThumbInfo(Stream stream, long offset, byte[] tempBytes, uint fileVersion, bool needImage)

        {

            fileOffset = offset;

            stream.Seek(fileOffset, SeekOrigin.Begin);

            stream.Read(tempBytes, 0, 64);


            int bytePtr = 0;

            string magic = Encoding.ASCII.GetString(tempBytes, bytePtr, 4); bytePtr += 4;

            if (!magic.Equals("CMMM"))

                throw new ApplicationException("Incorrect format.");


            entrySize = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;

            entryHash = BitConverter.ToUInt64(tempBytes, bytePtr); bytePtr += 8;


            if (fileVersion == WindowsVista)

            {

                bytePtr += 8; // wchar x 4

            }


            fileNameLength = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;

            paddingLength = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;

            dataLength = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;


            if (fileVersion >= Windows8)

            {

                imageWidth = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;

                imageHeight = BitConverter.ToUInt32(tempBytes, bytePtr); bytePtr += 4;

            }


            bytePtr += 4; // unknown


            dataChecksum = BitConverter.ToUInt64(tempBytes, bytePtr); bytePtr += 8;

            headerChecksum = BitConverter.ToUInt64(tempBytes, bytePtr); bytePtr += 8;


            if (!needImage || dataLength == 0 || dataLength > 0x1000000)

                return;


            stream.Seek(fileOffset + entrySize - dataLength, SeekOrigin.Begin);

            if (dataLength > tempBytes.Length)

                tempBytes = new byte[dataLength];


            stream.Read(tempBytes, 0, (int)dataLength);

            using (var mstream = new MemoryStream(tempBytes))

            {

                image = new Bitmap(mstream);

            }

        }


    }

}

详细解决方案在这里



查看完整回答
反对 回复 2022-10-15
  • 1 回答
  • 0 关注
  • 124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信