Exemple #1
0
        private void WriteNewFile(FileStream fs, WXAPKG_FILE file, string targetDir)
        {
            fs.Seek(file.m_offset, SeekOrigin.Begin);
            string   fileName = targetDir + "\\" + file.m_name;
            FileInfo fi       = new FileInfo(fileName);

            if (!Directory.Exists(fi.DirectoryName))
            {
                Directory.CreateDirectory(fi.DirectoryName);
            }
            Log($"抽取文件: {fi.FullName}");
            FileStream outFs = new FileStream(fi.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

            byte[] buffer      = new byte[32 * 1024];
            int    alreadyRead = 0;

            while (true)
            {
                if (alreadyRead + buffer.Length > file.m_size)
                {
                    int shouldRead = file.m_size - alreadyRead;
                    fs.Read(buffer, 0, shouldRead);
                    outFs.Write(buffer, 0, shouldRead);
                    alreadyRead += shouldRead;
                    break;
                }
                else
                {
                    fs.Read(buffer, 0, buffer.Length);
                    outFs.Write(buffer, 0, buffer.Length);
                    alreadyRead += buffer.Length;
                }
            }
            outFs.Flush();
            outFs.Close();
        }
Exemple #2
0
        public void Extractor(string wxFile, string targetDir)
        {
            FileStream fs = null;

            try
            {
                fs = new FileStream(wxFile, FileMode.Open, FileAccess.Read);

                // 获取头部信息
                WXAPKG_HEADER header = new WXAPKG_HEADER();

                // 第一个标识,固定为 0xBE
                header.m_first_mark = (byte)fs.ReadByte();
                if (0xBE != header.m_first_mark)
                {
                    Log("文件第一个标识有误,非 WXAPKG 格式文件!");

                    throw new Exception("文件第一个标识有误,非 WXAPKG 格式文件!");
                }

                // 版本号,0 -> 微信分发到客户端 1 -> 开发者上传到微信后台
                byte[] b_int = new byte[4];
                fs.Read(b_int, 0, b_int.Length);
                header.m_edition = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));

                // 索引段的长度
                fs.Read(b_int, 0, b_int.Length);
                header.m_index_info_length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));

                // 数据段的长度
                fs.Read(b_int, 0, b_int.Length);
                header.m_body_info_length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));

                // 第二个标识,固定为 0xED
                header.m_last_mark = (byte)fs.ReadByte();
                if (0xED != header.m_last_mark)
                {
                    Log("文件标识有误,非 WXAPKG 格式文件!");
                    throw new Exception("文件标识有误,非 WXAPKG 格式文件!");
                }

                // 文件数量
                fs.Read(b_int, 0, b_int.Length);
                header.m_file_count = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));


                List <WXAPKG_FILE> fileList = new List <WXAPKG_FILE>();
                // 获取每个文件的信息
                for (int i = 0; i < header.m_file_count; i++)
                {
                    WXAPKG_FILE file = new WXAPKG_FILE();

                    // 文件长度
                    fs.Read(b_int, 0, b_int.Length);
                    file.m_name_length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));

                    if (file.m_name_length > 255)
                    {
                        throw new Exception("错误的文件长度!");
                    }

                    // 文件名
                    byte[] b_name = new byte[file.m_name_length];
                    fs.Read(b_name, 0, b_name.Length);
                    file.m_name = Encoding.UTF8.GetString(b_name);

                    // 偏移
                    fs.Read(b_int, 0, b_int.Length);
                    file.m_offset = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));

                    // 大小
                    fs.Read(b_int, 0, b_int.Length);
                    file.m_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b_int, 0));
                    fileList.Add(file);
                }

                Log($"准备抽取文件到目录{targetDir}");
                for (int i = 0; i < fileList.Count; i++)
                {
                    WXAPKG_FILE file = fileList[i];

                    WriteNewFile(fs, file, targetDir);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                if (null != fs)
                {
                    fs.Close();
                }
            }
        }