主要是使用Rar.exe压缩解压文件(夹)(*.rar),另外还有使用SevenZipSharp.dll、zLib1.dll、7z.dll压缩解压文件(夹)(*.zip)。需要注意的几点如下:
1、注意Rar.exe软件存放的位置,此次放在了Debug目录下
2、SevenZipSharp.dll、zLib1.dll、7z.dll必须同时存在,否则常报“加载7z.dll错误”,项目引用时,只引用SevenZipSharp.dll即可
3、另外找不到7z.dll文件也会报错,测试时发现只用@"..\..\dll\7z.dll";相对路径时,路径是变化的,故此处才用了string libPath = System.AppDomain.CurrentDomain.BaseDirectory + @"..\..\dll\7z.dll";
SevenZip.SevenZipCompressor.SetLibraryPath(libPath);
。
。
。
具体代码如下:
Enums.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace CompressProj{/// <summary>/// 执行压缩命令结果/// </summary>public enum CompressResults{Success,SourceObjectNotExist,UnKnown}/// <summary>/// 执行解压缩命令结果/// </summary>public enum UnCompressResults{Success,SourceObjectNotExist,PasswordError,UnKnown}/// <summary>/// 进程运行结果/// </summary>public enum ProcessResults{ Success,Failed}}
CommonFunctions.cs
using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;namespace CompressProj{class CommonFunctions{#region 单例模式private static CommonFunctions uniqueInstance;private static object _lock = new object();private CommonFunctions() { }public static CommonFunctions getInstance() {if (null == uniqueInstance)//确认要实例化后再进行加锁,降低加锁的性能消耗。 {lock (_lock){if (null == uniqueInstance) {uniqueInstance = new CommonFunctions();}}}return uniqueInstance;}#endregion#region 进程/// <summary>/// 另起一进程执行命令/// </summary>/// <param name="exe">可执行程序(路径+名)</param>/// <param name="commandInfo">执行命令</param>/// <param name="workingDir">执行所在初始目录</param>/// <param name="processWindowStyle">进程窗口样式</param>/// <param name="isUseShellExe">Shell启动程序</param>public void ExecuteProcess(string exe, string commandInfo, string workingDir = "", ProcessWindowStyle processWindowStyle = ProcessWindowStyle.Hidden,bool isUseShellExe = false){ProcessStartInfo startInfo = new ProcessStartInfo();startInfo.FileName = exe;startInfo.Arguments = commandInfo;startInfo.WindowStyle = processWindowStyle;startInfo.UseShellExecute = isUseShellExe;if (!string.IsNullOrWhiteSpace(workingDir)){startInfo.WorkingDirectory = workingDir;}ExecuteProcess(startInfo);}/// <summary>/// 直接另启动一个进程/// </summary>/// <param name="startInfo">启动进程时使用的一组值</param>public void ExecuteProcess(ProcessStartInfo startInfo){try{Process process = new Process();process.StartInfo = startInfo;process.Start();process.WaitForExit();process.Close();process.Dispose();}catch(Exception ex){throw new Exception("进程执行失败:\n\r" + startInfo.FileName + "\n\r" + ex.Message);}}/// <summary>/// 去掉文件夹或文件的只读属性/// </summary>/// <param name="objectPathName">文件夹或文件全路径</param>public void Attribute2Normal(string objectPathName){if (true == Directory.Exists(objectPathName)){System.IO.DirectoryInfo directoryInfo = new System.IO.DirectoryInfo(objectPathName);directoryInfo.Attributes = FileAttributes.Normal;}else{File.SetAttributes(objectPathName,FileAttributes.Normal);}}#endregion }}
RarOperate.cs
using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace CompressProj{class RarOperate{private CommonFunctions commFuncs = CommonFunctions.getInstance();#region 单例模式private static RarOperate uniqueInstance;private static object _lock = new object();private RarOperate() { }public static RarOperate getInstance() {if (null == uniqueInstance)//确认要实例化后再进行加锁,降低加锁的性能消耗。 {lock (_lock){if (null == uniqueInstance) {uniqueInstance = new RarOperate();}}}return uniqueInstance;}#endregion#region 压缩/// <summary>/// 使用Rar.exe压缩对象/// </summary>/// <param name="rarRunPathName">Rar.exe路径+对象名</param>/// <param name="objectPathName">被压缩对象路径+对象名</param>/// <param name="objectRarPathName">对象压缩后路径+对象名</param>/// <returns></returns>public CompressResults CompressObject(string rarRunPathName, string objectPathName, string objectRarPathName,string password){try{//被压缩对象是否存在int beforeObjectNameIndex = objectPathName.LastIndexOf('\\');string objectPath = objectPathName.Substring(0, beforeObjectNameIndex);//System.IO.DirectoryInfo directoryInfo = new System.IO.DirectoryInfo(objectPathName);if (Directory.Exists(objectPathName)/*directoryInfo.Exists*/ == false && System.IO.File.Exists(objectPathName) == false){return CompressResults.SourceObjectNotExist;}//将对应字符串转换为命令字符串string rarCommand = "\"" + rarRunPathName + "\"";string objectPathNameCommand = "\"" + objectPathName + "\"";int beforeObjectRarNameIndex = objectRarPathName.LastIndexOf('\\');int objectRarNameIndex = beforeObjectRarNameIndex + 1;string objectRarName = objectRarPathName.Substring(objectRarNameIndex);string rarNameCommand = "\"" + objectRarName + "\"";string objectRarPath = objectRarPathName.Substring(0, beforeObjectRarNameIndex);//目标目录、文件是否存在if (System.IO.Directory.Exists(objectRarPath) == false){System.IO.Directory.CreateDirectory(objectRarPath);}else if (System.IO.File.Exists(objectRarPathName) == true){System.IO.File.Delete(objectRarPathName);}//Rar压缩命令string commandInfo = "a " + rarNameCommand + " " + objectPathNameCommand + " -y -p" + password + " -ep1 -r -s- -rr ";//另起一线程执行commFuncs.ExecuteProcess(rarCommand, commandInfo, objectRarPath, ProcessWindowStyle.Hidden);CompressRarTest(rarCommand, objectRarPathName, password);CorrectConfusedRar(objectRarPathName);}catch (Exception ex){MessageBox.Show(ex.Message);return CompressResults.UnKnown;}return CompressResults.Success;}#endregion#region 解压/// <summary>/// 解压:将文件解压到某个文件夹中。 注意:要对路径加上双引号,避免带空格的路径,在rar命令中失效/// </summary>/// <param name="rarRunPath">rar.exe的名称及路径</param>/// <param name="fromRarPath">被解压的rar文件路径</param>/// <param name="toRarPath">解压后的文件存放路径</param>/// <returns></returns>public UnCompressResults unCompressRAR(String rarRunPath, String objectRarPathName, String objectPath, string password){try{bool isFileExist = File.Exists(objectRarPathName);if (false == isFileExist){MessageBox.Show("解压文件不存在!" + objectRarPathName);return UnCompressResults.SourceObjectNotExist;}File.SetAttributes(objectRarPathName, FileAttributes.Normal);//去掉只读属性if (Directory.Exists(objectPath) == false){Directory.CreateDirectory(objectPath);}String rarCommand = "\"" + rarRunPath + "\"";String objectPathCommand = "\"" + objectPath + "\\\"";String commandInfo = "x \"" + objectRarPathName + "\" " + objectPath + " -y -p" + password;commFuncs.ExecuteProcess(rarCommand, commandInfo, objectPath, ProcessWindowStyle.Hidden);MessageBox.Show("解压缩成功!" + objectRarPathName);return UnCompressResults.Success;}catch{MessageBox.Show( "解压缩失败!" + objectRarPathName);return UnCompressResults.UnKnown;}}#endregion#region 进程#endregion#region 测试压缩文件/// <summary>/// 测试压缩后的文件是否正常。/// </summary>/// <param name="rarRunPath"></param>/// <param name="rarFilePathName"></param>public bool CompressRarTest(String rarRunPath, String rarFilePathName,string password){bool isOk = false;String commandInfo = "t -p" + password + " \"" + rarFilePathName + "\"";ProcessStartInfo startInfo = new ProcessStartInfo();startInfo.FileName = rarRunPath;startInfo.Arguments = commandInfo;startInfo.WindowStyle = ProcessWindowStyle.Hidden;startInfo.UseShellExecute = false;startInfo.RedirectStandardOutput = true;startInfo.CreateNoWindow = true;Process process = new Process();process.StartInfo = startInfo;process.Start();StreamReader streamReader = process.StandardOutput;process.WaitForExit();if (streamReader.ReadToEnd().ToLower().IndexOf("error") >= 0){MessageBox.Show("压缩文件已损坏!");isOk = false;}else{MessageBox.Show("压缩文件良好!");isOk = true;}process.Close();process.Dispose();return isOk;}/// <summary>/// 混淆Rar/// </summary>/// <param name="objectRarPathName">rar路径+名</param>/// <returns></returns>public bool ConfusedRar(string objectRarPathName){try{//混淆System.IO.FileStream fs = new FileStream(objectRarPathName, FileMode.Open);fs.WriteByte(0x53);fs.Close();return true;}catch (Exception ex){MessageBox.Show("混淆Rar失败!" + ex.Message);return false;}}/// <summary>/// 纠正混淆的Rar/// </summary>/// <param name="objectRarPathName">rar路径+名</param>/// <returns></returns>public bool CorrectConfusedRar(string objectRarPathName){bool isCorrect = false;try{//先判断一下待解压文件是否经过混淆FileStream fsRar = new FileStream(objectRarPathName, FileMode.Open, FileAccess.Read);int b = fsRar.ReadByte();fsRar.Close();if (b != 0x52)//R:0x52 原始开始值{string strTempFile = System.IO.Path.GetTempFileName();File.Copy(objectRarPathName, strTempFile, true);File.SetAttributes(strTempFile, FileAttributes.Normal);//去掉只读属性FileStream fs = new FileStream(strTempFile, FileMode.Open);fs.WriteByte(0x52);fs.Close();System.IO.File.Delete(objectRarPathName);File.Copy(strTempFile, objectRarPathName, true);}isCorrect = true;return isCorrect;}catch{MessageBox.Show("判断待解压文件是否经过混淆时出错!" + objectRarPathName);return isCorrect;}}#endregion#region #endregion}}
ZipOperate.cs
using SevenZip;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace CompressProj{class ZipOperate{#region 单例模式private static ZipOperate uniqueInstance;private static object _lock = new object();private ZipOperate() { }public static ZipOperate getInstance() {if (null == uniqueInstance)//确认要实例化后再进行加锁,降低加锁的性能消耗。{lock (_lock){if (null == uniqueInstance) {uniqueInstance = new ZipOperate();}}}return uniqueInstance;}#endregion#region 7zZip压缩、解压方法/// <summary>/// 压缩文件 /// </summary>/// <param name="objectPathName">压缩对象(即可以是文件夹|也可以是文件)</param>/// <param name="objectZipPathName">保存压缩文件的路径</param>/// <param name="strPassword">加密码</param>/// 测试压缩文件夹:压缩文件(objectZipPathName)不能放在被压缩文件(objectPathName)内,否则报“文件夹被另一进程使用中”错误。/// <returns></returns>public CompressResults Compress7zZip(String objectPathName, String objectZipPathName, String strPassword){try{///releases/view/51254 下载sevenzipsharp.dll//SevenZipSharp.dll、zLib1.dll、7z.dll必须同时存在,否则常报“加载7z.dll错误”string libPath = System.AppDomain.CurrentDomain.BaseDirectory + @"..\..\dll\7z.dll";SevenZip.SevenZipCompressor.SetLibraryPath(libPath);SevenZip.SevenZipCompressor sevenZipCompressor = new SevenZip.SevenZipCompressor();pressionLevel = pressionLevel.Fast;sevenZipCompressor.ArchiveFormat = SevenZip.OutArchiveFormat.Zip;//被压缩对象是否存在int beforeObjectNameIndex = objectPathName.LastIndexOf('\\');string objectPath = objectPathName.Substring(0, beforeObjectNameIndex);//System.IO.DirectoryInfo directoryInfo = new System.IO.DirectoryInfo(objectPathName);if (Directory.Exists(objectPathName)/*directoryInfo.Exists*/ == false && System.IO.File.Exists(objectPathName) == false){return CompressResults.SourceObjectNotExist;}int beforeObjectRarNameIndex = objectZipPathName.LastIndexOf('\\');int objectRarNameIndex = beforeObjectRarNameIndex + 1;//string objectZipName = objectZipPathName.Substring(objectRarNameIndex);string objectZipPath = objectZipPathName.Substring(0, beforeObjectRarNameIndex);//目标目录、文件是否存在if (System.IO.Directory.Exists(objectZipPath) == false){System.IO.Directory.CreateDirectory(objectZipPath);}else if (System.IO.File.Exists(objectZipPathName) == true){System.IO.File.Delete(objectZipPathName);}if (Directory.Exists(objectPathName)) //压缩对象是文件夹{if (String.IsNullOrEmpty(strPassword)){pressDirectory(objectPathName, objectZipPathName);}else{ pressDirectory(objectPathName, objectZipPathName, strPassword);}}else //压缩对象是文件 无加密方式{pressFiles(objectZipPathName, objectPathName);}return CompressResults.Success;}catch(Exception ex){MessageBox.Show("压缩文件失败!" + ex.Message);return CompressResults.UnKnown;}}/// <summary>/// 解压缩文件 /// </summary>/// <param name="zipFilePathName">zip文件具体路径+名</param>/// <param name="unCompressDir">解压路径</param>/// <param name="strPassword">解密码</param>/// <returns></returns>public UnCompressResults UnCompress7zZip(String zipFilePathName, String unCompressDir, String strPassword){try{//SevenZipSharp.dll、zLib1.dll、7z.dll必须同时存在,否则常报“加载7z.dll错误”而项目引用时,只引用SevenZipSharp.dll就可以了string libPath = System.AppDomain.CurrentDomain.BaseDirectory + @"..\..\dll\7z.dll";SevenZip.SevenZipCompressor.SetLibraryPath(libPath);bool isFileExist = File.Exists(zipFilePathName);if (false == isFileExist){MessageBox.Show("解压文件不存在!" + zipFilePathName);return UnCompressResults.SourceObjectNotExist;}File.SetAttributes(zipFilePathName, FileAttributes.Normal);//去掉只读属性if (Directory.Exists(unCompressDir) == false){Directory.CreateDirectory(unCompressDir);}SevenZip.SevenZipExtractor sevenZipExtractor;if (String.IsNullOrEmpty(strPassword)){sevenZipExtractor = new SevenZip.SevenZipExtractor(zipFilePathName);}else{sevenZipExtractor = new SevenZip.SevenZipExtractor(zipFilePathName, strPassword);}sevenZipExtractor.ExtractArchive(unCompressDir);sevenZipExtractor.Dispose();return UnCompressResults.Success;}catch(Exception ex){MessageBox.Show("解压缩文件失败!" + ex.Message);return UnCompressResults.UnKnown;}}#endregion}}
FileOperate.cs
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace CompressProj{class FileOperate{private RarOperate rarOperate = RarOperate.getInstance();#region 单例模式private static FileOperate uniqueInstance;private static object _lock = new object();private FileOperate() { }public static FileOperate getInstance() {if (null == uniqueInstance)//确认要实例化后再进行加锁,降低加锁的性能消耗。 {lock (_lock){if (null == uniqueInstance) {uniqueInstance = new FileOperate();}}}return uniqueInstance;}#endregion/// <summary>/// 打开文件/// </summary>/// <param name="openFileDialog"></param>/// <param name="filter"></param>/// <param name="isReadOnly">是否另外开启一使用该文件进程,防止该文件被操作</param>/// <returns></returns>public string OpenFile(OpenFileDialog openFileDialog,string filter,string openFileDialogTitle = "压缩文件",bool isReadOnly = false){string filePathName = string.Empty;if (string.IsNullOrEmpty(filter)){filter = "AllFiles(*.*)|*.*"; //TXT(*.txt)|*.txt|Word(*.doc,*.docx)|*.doc;*.docx|图像文件(*.gif;*.jpg;*.jpeg;*.png;*.psd)|*.gif;*.jpg;*.jpeg;*.png;*.psd| }openFileDialog.Filter = filter;DialogResult dResult = openFileDialog.ShowDialog();if (dResult == DialogResult.OK){string defaultExt = ".docx";//string filter = string.Empty;//openFileDialog.ReadOnlyChecked = isReadOnly;openFileDialog.SupportMultiDottedExtensions = true;openFileDialog.AutoUpgradeEnabled = true;openFileDialog.AddExtension = true;openFileDialog.CheckPathExists = true;openFileDialog.CheckFileExists = true;openFileDialog.DefaultExt = defaultExt;openFileDialog.Multiselect = true;openFileDialog.ShowReadOnly = true;openFileDialog.Title = openFileDialogTitle;openFileDialog.ValidateNames = true;openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Templates);//添加后界面没变化 Win7 + VS11openFileDialog.ShowHelp = true;filePathName = openFileDialog.FileName;if (true == isReadOnly){openFileDialog.OpenFile(); //打开只读文件,即开启一使用该文件进程,防止其他进程操作该文件}openFileDialog.Dispose();}return filePathName;}/// <summary>/// 打开文件/// </summary>/// <param name="saveFileDialog"></param>/// <param name="filter"></param>/// <param name="isReadOnly"></param>/// <returns></returns>public string SaveFile(SaveFileDialog saveFileDialog, string filter,string saveFileDialogTitle = "保存文件", bool isReadOnly = false){string filePathName = string.Empty;if (string.IsNullOrEmpty(filter)){filter = "AllFiles(*.*)|*.*"; //TXT(*.txt)|*.txt|Word(*.doc,*.docx)|*.doc;*.docx|图像文件(*.gif;*.jpg;*.jpeg;*.png;*.psd)|*.gif;*.jpg;*.jpeg;*.png;*.psd| }saveFileDialog.Filter = filter;DialogResult dResult = saveFileDialog.ShowDialog();if (dResult == DialogResult.OK){string defaultExt = ".docx";//string filter = string.Empty;//string saveFileDialogTitle = "保存文件";saveFileDialog.SupportMultiDottedExtensions = true;saveFileDialog.AutoUpgradeEnabled = true;saveFileDialog.AddExtension = true;saveFileDialog.CheckPathExists = true;saveFileDialog.CheckFileExists = true;saveFileDialog.DefaultExt = defaultExt;saveFileDialog.RestoreDirectory = true;saveFileDialog.OverwritePrompt = true;saveFileDialog.Title = saveFileDialogTitle;saveFileDialog.ValidateNames = true;saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Templates);//添加后界面没变化 Win7 + VS11saveFileDialog.ShowHelp = true;filePathName = saveFileDialog.FileName;if (true == isReadOnly){saveFileDialog.OpenFile(); //打开只读文件,即开启一使用该文件进程,防止其他进程操作该文件}saveFileDialog.Dispose();}return filePathName;}}}
测试调用代码如下:
RarForm.cs
using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Diagnostics;using System.Drawing;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace CompressProj{public partial class RarForm : Form{private FileOperate fileOperate = FileOperate.getInstance();private RarOperate rarOperate = RarOperate.getInstance();private ZipOperate zipOperate = ZipOperate.getInstance();public RarForm(){InitializeComponent();}private void btnCompress_Click(object sender, EventArgs e){string filter = "TXT(*.txt)|*.txt|Word(*.doc,*.docx)|*.doc;*.docx|AllFiles(*.*)|*.*";string openFileDialogTitle = "压缩文件";string compressFilePathName = fileOperate.OpenFile(this.openFileDialog1, filter, openFileDialogTitle,true);if (string.IsNullOrEmpty(compressFilePathName) || string.IsNullOrWhiteSpace(compressFilePathName)){return;}this.openFileDialog1.HelpRequest += new EventHandler(openFileDialog1_HelpRequest);string objectRarPathName = compressFilePathName.Substring(0,compressFilePathName.LastIndexOf('.')) + ".rar";string rarPathName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Rar.exe";string password = string.Empty;//"shenc";CompressResults compressResult = pressObject(rarPathName, compressFilePathName, objectRarPathName, password);if (CompressResults.Success == compressResult){MessageBox.Show(objectRarPathName);}}private void openFileDialog1_HelpRequest(object sender, EventArgs e){MessageBox.Show("HelpRequest!");}private void btnUncompress_Click(object sender, EventArgs e){string filter = "Rar(*.rar)|*.rar";string openFileDialogTitle = "解压文件";string unCompressFilePathName = fileOperate.OpenFile(this.openFileDialog1, filter, openFileDialogTitle, false);if (string.IsNullOrEmpty(unCompressFilePathName) || string.IsNullOrWhiteSpace(unCompressFilePathName)){return;}string objectPath = unCompressFilePathName.Substring(0, unCompressFilePathName.LastIndexOf('.'));string rarPathName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Rar.exe";string password = string.Empty;//"shenc";UnCompressResults unCompressResult = rarOperate.unCompressRAR(rarPathName, unCompressFilePathName, objectPath, password);if (UnCompressResults.Success == unCompressResult){MessageBox.Show(objectPath);}}private void btnCompressZip_Click(object sender, EventArgs e){string filter = "TXT(*.txt)|*.txt|Word(*.doc,*.docx)|*.doc;*.docx|AllFiles(*.*)|*.*";string openFileDialogTitle = "压缩文件";string compressFilePathName = fileOperate.OpenFile(this.openFileDialog1, filter, openFileDialogTitle, false);if (string.IsNullOrEmpty(compressFilePathName) || string.IsNullOrWhiteSpace(compressFilePathName)){return;}//this.openFileDialog1.HelpRequest += new EventHandler(openFileDialog1_HelpRequest);string password = string.Empty;//"shenc";string objectZipPathName = compressFilePathName.Substring(0, compressFilePathName.LastIndexOf('.')) + ".zip";CompressResults compressResult = press7zZip(compressFilePathName, objectZipPathName, password); //压缩文件////测试压缩文件夹:压缩文件不能放在被压缩文件内,否则报“文件夹被另一进程使用中”错误。//string objectPath = compressFilePathName.Substring(0, compressFilePathName.LastIndexOf('\\'));//objectZipPathName = objectPath + ".zip";//CompressResults compressResult = press7zZip(objectPath, objectZipPathName, password); //压缩文件夹if (CompressResults.Success == compressResult){MessageBox.Show(objectZipPathName);}}private void btnUnCompressZip_Click(object sender, EventArgs e){string filter = "Zip(*.zip)|*.zip";string openFileDialogTitle = "解压文件";string unCompressFilePathName = fileOperate.OpenFile(this.openFileDialog1, filter, openFileDialogTitle, false);if (string.IsNullOrEmpty(unCompressFilePathName) || string.IsNullOrWhiteSpace(unCompressFilePathName)){return;}string objectPath = unCompressFilePathName.Substring(0, unCompressFilePathName.LastIndexOf('.'));string password = string.Empty;//"shenc";UnCompressResults unCompressResult = zipOperate.UnCompress7zZip(unCompressFilePathName, objectPath, password);if (UnCompressResults.Success == unCompressResult){MessageBox.Show(objectPath);}}}}
如果觉得《C#压缩 解压缩文件(夹)(rar zip)》对你有帮助,请点赞、收藏,并留下你的观点哦!