/// <summary>
        /// Get resources need to pack and save meta.
        /// </summary>
        /// <param name="resNeedToPack">The output list of resources need to pack.</param>
        protected void GatherResAndSaveMeta(Dictionary <string, string> resNeedToPack)
        {
            StreamWriter swMeta = null;

            try
            {
                foreach (KeyValuePair <string, string> resPath in resourceFilePath)
                {
                    bool?undcPath = RelativePathConverter.IsRelativePath(resPath.Value);
                    if (undcPath == true)
                    {
                        if (string.IsNullOrEmpty(projPath))
                        {
                            throw new InvalidRelativeResPathException(resPath.Value);
                        }
                        string sp = Path.GetFullPath(Path.Combine(projPath, resPath.Value));
                        resNeedToPack.Add(resPath.Key, sp);
                    }
                    else if (undcPath == false)
                    {
                        resNeedToPack.Add(resPath.Key, resPath.Value);
                    }
                }
                swMeta = new StreamWriter(projMetaPath, false);
                foreach (KeyValuePair <string, string> resPath in resourceFilePath)
                {
                    bool?undcPath = RelativePathConverter.IsRelativePath(resPath.Value);
                    if (undcPath == true)
                    {
                        if (string.IsNullOrEmpty(projPath))
                        {
                            throw new InvalidRelativeResPathException(resPath.Value);
                        }
                        string sp = Path.GetFullPath(Path.Combine(projPath, resPath.Value));
                        swMeta.WriteLine(GetMD5HashFromFile(sp) + "|" + sp + "|" + resPath.Key);
                    }
                    else if (undcPath == false)
                    {
                        swMeta.WriteLine(GetMD5HashFromFile(resPath.Value) + "|" + resPath.Value + "|" + resPath.Key);
                    }
                }
                swMeta.Close();
            }
            catch (System.Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                if (swMeta != null)
                {
                    swMeta.Close();
                }
            }
        }
 /// <summary>
 /// Get all resources need to pack.
 /// </summary>
 /// <param name="resNeedToPack">The output list of resources need to pack.</param>
 protected void GatherAllRes(Dictionary <string, string> resNeedToPack)
 {
     if (File.Exists(projMetaPath))
     {
         File.Delete(projMetaPath);
     }
     foreach (KeyValuePair <string, string> resPath in resourceFilePath)
     {
         bool?undcPath = RelativePathConverter.IsRelativePath(resPath.Value);
         if (undcPath == true)
         {
             if (string.IsNullOrEmpty(projPath))
             {
                 throw new InvalidRelativeResPathException(resPath.Value);
             }
             resNeedToPack.Add(resPath.Key, Path.GetFullPath(Path.Combine(projPath, resPath.Value)));
         }
         else if (undcPath == false)
         {
             resNeedToPack.Add(resPath.Key, resPath.Value);
         }
     }
 }
        protected void PackFileUsingInfo_old2(IAppSettings currentApp, List <string> resNeedToPack, Dictionary <string, string> resPathToMD5)
        {
            //Pack File using info
            FileStream   packBatS = null;
            StreamWriter packBat  = null;

            try
            {
                packBatS = new FileStream(rootZipPackPath, FileMode.Create);
                packBat  = new StreamWriter(packBatS, Encoding.Default);
                bool isRenew = false;
                if (resPathToMD5.Count != 0 || !currentApp.SaveResMeta)
                {
                    isRenew = true;
                    if (File.Exists(targetZipPath))
                    {
                        File.Delete(targetZipPath);
                    }
                }
                packBat.WriteLine(zipExePath + " u -tzip -mcu=on \"" + targetZipPath
                                  + "\" \"" + rootLuaPath + "\" \"" + projLuaPath + "\"");

                if (!isRenew)
                {
                    foreach (string resPath in resNeedToPack)
                    {
                        packBat.WriteLine(zipExePath + " u -tzip -mcu=on \"" + targetZipPath + "\" \""
                                          + resPath + "\"");
                    }
                }
                else
                {
                    foreach (KeyValuePair <string, string> resPath in resourceFilePath)
                    {
                        bool?undcPath = RelativePathConverter.IsRelativePath(resPath.Value);
                        if (undcPath == true)
                        {
                            if (string.IsNullOrEmpty(projPath))
                            {
                                throw new InvalidRelativeResPathException(resPath.Value);
                            }
                            packBat.WriteLine(zipExePath + " u -tzip -mcu=on \"" + targetZipPath + "\" \""
                                              + Path.GetFullPath(Path.Combine(projPath, resPath.Value)) + "\"");
                        }
                        else if (undcPath == false)
                        {
                            packBat.WriteLine(zipExePath + " u -tzip -mcu=on \"" + targetZipPath + "\" \""
                                              + resPath + "\"");
                        }
                    }
                }

                if (currentApp.PackProj)
                {
                    if (!string.IsNullOrEmpty(source.DocPath))
                    {
                        packBat.WriteLine(zipExePath + " u -tzip -mcu=on \"" + targetZipPath + "\" \""
                                          + source.DocPath + "\"");
                    }
                }
                packBat.Close();
                Process pack = new Process
                {
                    StartInfo = new ProcessStartInfo(rootZipPackPath)
                    {
                        UseShellExecute = true,
                        CreateNoWindow  = false
                    }
                };
                pack.Start();
                pack.WaitForExit();
                //catch { }
            }
            catch (System.Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                if (packBat != null)
                {
                    packBat.Close();
                }
                if (packBatS != null)
                {
                    packBatS.Close();
                }
                if (File.Exists(projLuaPath))
                {
                    File.Delete(projLuaPath);
                }
            }
        }
        /// <summary>
        /// Generate pack batch and execute it by given information.
        /// </summary>
        /// <param name="currentApp">The current <see cref="App"/>.</param>
        /// <param name="resNeedToPack">The output list of resources need to pack.</param>
        /// <param name="resPathToMD5">The dictionary of resource archivePath -> (directoryPath, MD5 Hash)
        /// of the resource.</param>
        /// <param name="includeRoot">Whether regenerates root.lua.</param>
        /// <param name="preserveZip">Whether zip file must be preserved.</param>
        protected void PackFileUsingInfo(IAppSettings currentApp, Dictionary <string, string> resNeedToPack
                                         , Dictionary <string, Tuple <string, string> > resPathToMD5, bool includeRoot, bool preserveZip = false)
        {
            Dictionary <string, string> entry2File = new Dictionary <string, string>();
            string temp;

            try
            {
                if (includeRoot)
                {
                    entry2File.Add(Path.GetFileName(rootLuaPath), rootLuaPath);
                }
                entry2File.Add(Path.GetFileName(projLuaPath), projLuaPath);
                if (currentApp.SaveResMeta)
                {
                    foreach (KeyValuePair <string, string> resPath in resNeedToPack)
                    {
                        entry2File.Add(resPath.Key, resPath.Value);
                    }
                    foreach (KeyValuePair <string, Tuple <string, string> > kvp in resPathToMD5)
                    {
                        entry2File.Add(kvp.Key, kvp.Value.Item1);
                    }
                }
                else
                {
                    //if (File.Exists(targetZipPath)) File.Delete(targetZipPath);
                    foreach (KeyValuePair <string, string> resPath in resourceFilePath)
                    {
                        bool?undcPath = RelativePathConverter.IsRelativePath(resPath.Value);
                        if (undcPath == true)
                        {
                            if (string.IsNullOrEmpty(projPath))
                            {
                                throw new InvalidRelativeResPathException(resPath.Value);
                            }
                            temp = Path.GetFullPath(Path.Combine(projPath, resPath.Value));
                            entry2File.Add(resPath.Key, temp);
                        }
                        else if (undcPath == false)
                        {
                            entry2File.Add(resPath.Key, resPath.Value);
                        }
                    }
                }

                if (currentApp.PackProj)
                {
                    if (!string.IsNullOrEmpty(source.DocPath))
                    {
                        entry2File.Add(source.RawDocName, source.DocPath);
                    }
                }
                int           entryCount   = entry2File.Count;
                float         currentCount = 0;
                ZipCompressor compressor;
                if (currentApp.BatchPacking)
                {
                    compressor = new ZipCompressorBatch(targetZipPath, zipExePath, rootZipPackPath);
                }
                else
                {
                    compressor = new ZipCompressorInternal(targetZipPath);
                }
                foreach (string s in compressor.PackByDictReporting(entry2File, !currentApp.SaveResMeta && !preserveZip))
                {
                    ProgressChanged_Private?.Invoke(this, new ProgressChangedEventArgs(Convert.ToInt32(currentCount), s));
                    currentCount += 1.0f / entryCount;
                }
            }
            catch (System.Exception e)
            {
                MessageBox.Show("Pack process failed.\n" + e.ToString());
            }
            finally
            {
                if (File.Exists(projLuaPath))
                {
                    File.Delete(projLuaPath);
                }
            }
        }
        /// <summary>
        /// Get resources need to pack by meta.
        /// </summary>
        /// <param name="resNeedToPack">The output list of resources need to pack.</param>
        /// <param name="resPathToMD5">The dictionary of resource archivePath -> (directoryPath, MD5 Hash)
        /// of the resource.</param>
        protected void GatherResByResMeta(Dictionary <string, string> resNeedToPack
                                          , Dictionary <string, Tuple <string, string> > resPathToMD5)
        {
            StreamReader srMeta = null;
            StreamWriter swMeta = null;

            try
            {
                srMeta = new StreamReader(projMetaPath);
                string temp;
                while (!srMeta.EndOfStream)
                {
                    temp = srMeta.ReadLine();
                    string[] scom             = temp.Split('|');
                    string   spathWithArchive = "";
                    for (int i = 1; i < scom.Length; i++)
                    {
                        spathWithArchive += scom[i] + "|";
                    }
                    string md5 = scom[0];
                    scom = spathWithArchive.Split('|');
                    string sArchive = "";
                    for (int i = 1; i < scom.Length; i++)
                    {
                        sArchive += scom[i];
                    }
                    string spath = scom[0];
                    if (!resPathToMD5.ContainsKey(sArchive))
                    {
                        resPathToMD5.Add(sArchive, new Tuple <string, string>(spath, md5));
                    }
                }
                srMeta.Close();
                swMeta = new StreamWriter(projMetaPath, false);
                foreach (KeyValuePair <string, string> resPath in resourceFilePath)
                {
                    string resFullPath = null;
                    bool?  undcPath    = RelativePathConverter.IsRelativePath(resPath.Value);
                    if (undcPath == true)
                    {
                        if (string.IsNullOrEmpty(projPath))
                        {
                            throw new InvalidRelativeResPathException(resPath.Value);
                        }
                        resFullPath = Path.GetFullPath(Path.Combine(projPath, resPath.Value));
                    }
                    else if (undcPath == false)
                    {
                        resFullPath = resPath.Value;
                    }
                    if (undcPath != null)
                    {
                        if (resPathToMD5.ContainsKey(resPath.Key))
                        {
                            if (GetMD5HashFromFile(resFullPath) != resPathToMD5[resPath.Key].Item2)
                            {
                                resNeedToPack.Add(resPath.Key, resFullPath);
                            }
                        }
                        else
                        {
                            resNeedToPack.Add(resPath.Key, resFullPath);
                        }
                        resPathToMD5.Remove(resPath.Key);
                        swMeta.WriteLine(GetMD5HashFromFile(resFullPath) + "|" + resFullPath + "|" + resPath.Key);
                    }
                }
            }
            catch (System.Exception e)
            {
                MessageBox.Show(e.ToString());
            }
            finally
            {
                if (srMeta != null)
                {
                    srMeta.Close();
                }
                if (swMeta != null)
                {
                    swMeta.Close();
                }
            }
        }