C#调用Winrar进行压缩解压缩

本文为阿良.NET原创。转载请注明转自阿良.NET和本文的链接。

调用Winrar.exe压缩和解压缩源代码

using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace cjl.Utility
{
    /// <summary>
    /// 调用Winrar.exe压缩和解压缩。
    /// </summary>
    public class Winrar
    {
        private string winrarExe;
        private string password;

        private static Regex regexDir = new Regex(@"^[a-zA-Z]:[^\n]*\\$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static Regex regexFile = new Regex(@"^[a-zA-Z]:\\.+\.rar$", RegexOptions.IgnoreCase | RegexOptions.Compiled);


        /// <summary>
        /// 构造函数。
        /// </summary>
        /// <param name="dirOfWinrarExe">Winrar.exe所在的目录(绝对路径)。
        /// 请你拷贝Winrar.exe到一个你有读写权限的目录,然后用此目录作为参数。否则将不能执行。
        /// </param>
        /// <param name="password">用来压缩或解压缩时使用的密码,如果没有密码,请用另一无password参数的构造函数。</param>
        /// <remarks>
        /// 调用方法
        /// <code>
        /// <xmp>
        /// string dirOfWinrarExe = @"D:\Winrar\";
        ///    Winrar rar = new Winrar(dirOfWinrarExe);
        ///   
        ///    StringCollection dirs = new StringCollection();
        ///    dirs.Add(@"C:\A\");
        ///    dirs.Add(@"C:\B\");
        ///   
        ///    StringCollection files = new StringCollection();
        ///    files.Add(@"D:\a.txt");
        ///    files.Add(@"D:\b.htm");
        ///   
        ///    string rarFile = @"D:\backup.rar";
        ///    bool isDeleteSource = false;
        ///    rar.Compress(dirs, files, rarFile, isDeleteSource);
        ///   
        ///    string dir = @"D:\A\";
        ///    rar.CompressDir(dir, rarFile, isDeleteSource);
        ///   
        ///    string file = @"C:\a.txt";
        ///    rar.CompressFile(file, rarFile, isDeleteSource);
        ///    </xmp>
        /// </code>
        /// </remarks>
        public Winrar(string dirOfWinrarExe, string password)
        {
            CheckDirectoryName(dirOfWinrarExe);
            this.winrarExe = dirOfWinrarExe + "Winrar.exe";

            this.password = CheckPassword(password);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dirOfWinrarExe">Winrar.exe所在的目录(绝对路径)。
        /// 请你拷贝Winrar.exe到一个你有读写权限的目录,然后用此目录作为参数。否则将不能执行。
        /// </param>
        public Winrar(string dirOfWinrarExe)
        {
            CheckDirectoryName(dirOfWinrarExe);
            this.winrarExe = dirOfWinrarExe + "Winrar.exe";

            this.password = null;
        }


        private static void CheckDirectoryNames(StringCollection directoryNames)
        {
            if (directoryNames == null)
            {
                return;
            }
            foreach (string directoryName in directoryNames)
            {
                if (directoryName == null)
                {
                    continue;
                }
                CheckDirectoryName(directoryName);
            }
        }

        private static void CheckDirectoryName(string directoryName)
        {
            directoryName = PhysicalPath.ToWellFormat(directoryName);
            if (directoryName == null)
            {
                throw new Exception("目录名不可以为null。");
            }

            if (!regexDir.IsMatch(directoryName))
            {
                throw new Exception(@"目录名称请用绝对路径,须以“\”结束。如:C:\Windows\。");
            }

        }

        /// <summary>
        /// 检查密码是否符合格式。
        /// </summary>
        /// <param name="password">密码</param>
        /// <returns>密码</returns>
        private static string CheckPassword(string password)
        {
            if (password == null)
            {
                throw new Exception("密码不可以为null。如不要密码,请用另一无password参数的构造函数。");
            }

            Regex regex = new Regex(@"^\w+$");
            if (!regex.IsMatch(password))
            {
                throw new Exception("密码请用字母,数字,下画线。");
            }

            return password;
        }

        /// <summary>
        /// 检查是否扩展名为.rar的文件名。
        /// </summary>
        /// <param name="rarFile">winrar文件名(绝对路径)</param>
        /// <returns>winrar文件名(绝对路径)</returns>
        private static void CheckRarFile(string rarFile)
        {
            if (rarFile == null)
            {
                throw new Exception("文件名不可以为null。");
            }

            if (!regexFile.IsMatch(rarFile))
            {
                throw new Exception(@"文件名称请用绝对路径,须以“扩展名.rar”结束。如:C:\Windows\aa.rar");
            }

        }

        /// <summary>
        /// 生成一个临时文件(backup.lst)。该文件中每一行包括一个要压缩的文件名。
        /// 该文件名用于构造命令winrar a backup.rar @backup.rar。请参考winrar.exe帮助
        /// </summary>
        /// <param name="files">要压缩的文件名数组。</param>
        /// <param name="lstFile">临时文件名,用于构造命令winrar a backup.rar @backup.rar</param>
        private void CreateLstFile(StringCollection dirs, StringCollection files, out string lstFile)
        {
            string path = winrarExe.Substring(0, winrarExe.LastIndexOf("\\") + 1);
            string filename = Guid.NewGuid().ToString() + ".lst";
            lstFile = path + filename;


            StreamWriter sw = new StreamWriter(lstFile, false, Encoding.GetEncoding("gb2312"));


            if (files != null)
            {
                foreach (string file in files)
                {
                    sw.WriteLine(file);
                }
            }

            if (dirs != null)
            {
                foreach (string dir in dirs)
                {
                    sw.WriteLine(dir);
                }
            }

            sw.Close();
        }

        /// <summary>
        /// 检查是文件名是否符合格式(绝对路径)。
        /// </summary>
        /// <param name="files">文件名数组(绝对路径)。</param>
        private static void CheckFiles(StringCollection files)
        {
            if (files == null)
            {
                return;
            }
            Regex regex = new Regex(@"[a-zA-Z]:\\.+\..+");

            foreach (string file in files)
            {
                if (file == null)
                {
                    throw new Exception("文件名不可以为null。");
                }

                if (!regex.IsMatch(file))
                {
                    throw new Exception(@"文件名称请用绝对路径,并注意格式。如:C:\Windows\aa.txt");
                }
            }

        }

        /// <summary>
        /// 压缩指定文件列表。
        /// </summary>
        /// <param name="rarFile">压缩后的文件名(绝对路径)。</param>
        /// <param name="deleteSource">压缩后是否删除源文件列表。</param>
        /// <param name="files">要压缩的文件列表(绝对路径)。</param>
        public void Compress(StringCollection dirs, StringCollection files, string rarFile, bool deleteSource)
        {
            CheckRarFile(rarFile);
            if (File.Exists(rarFile))
            {
                File.Delete(rarFile);
            }

            CheckDirectoryNames(dirs);
            CheckFiles(files);

            string lstFile;
            this.CreateLstFile(dirs, files, out lstFile);


            Process p = new Process();
            // 需要启动的程序名
            p.StartInfo.FileName = winrarExe;
            // 参数
            string arguments = @"a -ibck-r -y -o+ -ep1 ";
            if (password != null)
            {
                arguments += " -p" + password;
            }
            arguments += " " + rarFile + " @" + lstFile + " VsProject\\";

            p.StartInfo.Arguments = arguments;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.Start(); //启动 
            p.WaitForExit();
            p.Close();

            if (deleteSource)
            {
                if (dirs != null)
                {
                    foreach (string dir in dirs)
                    {
                        if (Directory.Exists(dir))
                        {
                            Directory.Delete(dir, true);
                        }
                    }
                }
                if (files != null)
                {
                    foreach (string file in files)
                    {
                        if (File.Exists(file))
                        {
                            File.Delete(file);
                        }
                    }
                }
            }

            File.Delete(lstFile);
        }

        /// <summary>
        /// 压缩目录
        /// </summary>
        /// <param name="dir">文件(绝对路径)</param>
        /// <param name="rarFileToSave">压缩后的文件名(绝对路径)。</param>
        /// <param name="deleteSource">压缩后是否删除目录</param>
        /// </summary>
        public void CompressDir(string dir, string rarFileToSave, bool deleteSource)
        {
            StringCollection dirs = new StringCollection();
            dirs.Add(dir);
            Compress(dirs, null, rarFileToSave, deleteSource);
        }

        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="file">文件(绝对路径)</param>
        /// <param name="rarFileToSave">压缩后的文件名(绝对路径)。</param>
        /// <param name="deleteSource">压缩后是否删除文件</param>
        public void CompressFile(string file, string rarFileToSave, bool deleteSource)
        {
            StringCollection files = new StringCollection();
            files.Add(file);
            Compress(null, files, rarFileToSave, deleteSource);
        }

        /// <summary>
        /// 解压缩rar文件。
        /// </summary>
        /// <param name="rarFile">rar文件(绝对路径)。</param>
        /// <param name="dirToSave">解压缩保存的目录。</param>
        /// <param name="deleteRarFile">解压缩后是否删除rar文件。</param>
        public void Decompress(string rarFile, string dirToSave, bool deleteRarFile)
        {
            CheckDirectoryName(dirToSave);
            CheckRarFile(rarFile);

            Process p = new Process();
            // 需要启动的程序名
            p.StartInfo.FileName = winrarExe;
            // 参数
            string arguments = @"x -inul -y -o+ -ep1";

            if (password != null)
            {
                arguments += " -p" + password;
            }
            arguments += " " + rarFile + " " + dirToSave;

            p.StartInfo.Arguments = arguments;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.Start(); //启动

            p.WaitForExit();

            if (deleteRarFile)
            {
                File.Delete(rarFile);
            }
        }


    }
}

posted @ 2006-04-17 14:12  萧萧  阅读(244)  评论(0)    收藏  举报