unrar.dll是winrar提供给开发者的开发库,可以用自己的代码解压rar压缩文件及其分卷压缩文件。下载地址为:https://www.rarlab.com/rar_add.htm ,开发包里有dll和示例及其文档,但是unrar.dll好像对分卷支持不好,如果要解压分卷,按照此博文修改示例里的unrar.cs,即可完美支持分卷解压缩rar文件。
在编写自主压缩解压软件 FiveStarZip 时,使用unrar.dll解压rar分卷文件时遇到总是报错问题,研究了一下,发现了问题。
我是用的是2020年最新版的unrar.dll,原来unrar.dll应用的示例文件unrar.cs里的完整代码是这样,通过自己写代码就可以调用这个里的代码,并加载unrar.dll实现解压缩rar压缩文件,但是此代码对于rar分卷解压缩总是报错:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections;
/* Author: Michael A. McCloskey
* Company: Schematrix
* Version: 20040714
*
* Personal Comments:
* I created this unrar wrapper class for personal use
* after running into a number of issues trying to use
* another COM unrar product via COM interop. I hope it
* proves as useful to you as it has to me and saves you
* some time in building your own products.
*/
namespace Schematrix
{
#region Event Delegate Definitions
/// <summary>
/// Represents the method that will handle data available events
/// </summary>
public delegate void DataAvailableHandler(object sender, DataAvailableEventArgs e);
/// <summary>
/// Represents the method that will handle extraction progress events
/// </summary>
public delegate void ExtractionProgressHandler(object sender, ExtractionProgressEventArgs e);
/// <summary>
/// Represents the method that will handle missing archive volume events
/// </summary>
public delegate void MissingVolumeHandler(object sender, MissingVolumeEventArgs e);
/// <summary>
/// Represents the method that will handle new volume events
/// </summary>
public delegate void NewVolumeHandler(object sender, NewVolumeEventArgs e);
/// <summary>
/// Represents the method that will handle new file notifications
/// </summary>
public delegate void NewFileHandler(object sender, NewFileEventArgs e);
/// <summary>
/// Represents the method that will handle password required events
/// </summary>
public delegate void PasswordRequiredHandler(object sender, PasswordRequiredEventArgs e);
#endregion
/// <summary>
/// Wrapper class for unrar DLL supplied by RARSoft.
/// Calls unrar DLL via platform invocation services (pinvoke).
/// DLL is available at http://www.rarlab.com/rar/UnRARDLL.exe
/// </summary>
public class Unrar : IDisposable
{
#region Unrar DLL enumerations
/// <summary>
/// Mode in which archive is to be opened for processing.
/// </summary>
public enum OpenMode
{
/// <summary>
/// Open archive for listing contents only
/// </summary>
List=0,
/// <summary>
/// Open archive for testing or extracting contents
/// </summary>
Extract=1
}
private enum RarError : uint
{
EndOfArchive=10,
InsufficientMemory=11,
BadData=12,
BadArchive=13,
UnknownFormat=14,
OpenError=15,
CreateError=16,
CloseError=17,
ReadError=18,
WriteError=19,
BufferTooSmall=20,
UnknownError=21
}
private enum Operation : uint
{
Skip=0,
Test=1,
Extract=2
}
private enum VolumeMessage : uint
{
Ask=0,
Notify=1
}
[Flags]
private enum ArchiveFlags : uint
{
Volume=0x1, // Volume attribute (archive volume)
CommentPresent=0x2, // Archive comment present
Lock=0x4, // Archive lock attribute
SolidArchive=0x8, // Solid attribute (solid archive)
NewNamingScheme=0x10, // New volume naming scheme ('volname.partN.rar')
AuthenticityPresent=0x20, // Authenticity information present
RecoveryRecordPresent=0x40, // Recovery record present
EncryptedHeaders=0x80, // Block headers are encrypted
FirstVolume=0x100 // 0x0100 - First volume (set only by RAR 3.0 and later)
}
private enum CallbackMessages : uint
{
VolumeChange=0,
ProcessData=1,
NeedPassword=2
}
#endregion
#region Unrar DLL structure definitions
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
private struct RARHeaderData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
public string ArcName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
public string FileName;
public uint Flags;
public uint PackSize;
public uint UnpSize;
public uint HostOS;
public uint FileCRC;
public uint FileTime;
public uint UnpVer;
public uint Method;
public uint FileAttr;
[MarshalAs(UnmanagedType.LPStr)]
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
public void Initialize()
{
this.CmtBuf=new string((char)0, 65536);
this.CmtBufSize=65536;
}
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct RARHeaderDataEx
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=512)]
public string ArcName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)]
public string ArcNameW;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=512)]
public string FileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)]
public string FileNameW;
public uint Flags;
public uint PackSize;
public uint PackSizeHigh;
public uint UnpSize;
public uint UnpSizeHigh;
public uint HostOS;
public uint FileCRC;
public uint FileTime;
public uint UnpVer;
public uint Method;
public uint FileAttr;
[MarshalAs(UnmanagedType.LPStr)]
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=1024)]
public uint[] Reserved;
public void Initialize()
{
this.CmtBuf=new string((char)0, 65536);
this.CmtBufSize=65536;
}
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct RAROpenArchiveData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
public string ArcName;
public uint OpenMode;
public uint OpenResult;
[MarshalAs(UnmanagedType.LPStr)]
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
public void Initialize()
{
this.CmtBuf=new string((char)0,65536);
this.CmtBufSize=65536;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct RAROpenArchiveDataEx
{
[MarshalAs(UnmanagedType.LPStr)]
public string ArcName;
[MarshalAs(UnmanagedType.LPWStr)]
public string