我从rarlab.com下载了rarlab.com,包括unrar.dll和unrar.cs类到我的C# WPF项目中。
它提取单个档案(即使设置了密码):
string source = "d:\\unrartest\\compressed\\myarchive.part1.rar";
string dest = "d:\\unrartest\\extracted";
Unrar unrar = new Unrar();
unrar.Password = "password_of_myarchive";
unrar.Open(@source, Unrar.OpenMode.Extract);
while (unrar.ReadHeader())
{
unrar.ExtractToDirectory(@dest);
}
unrar.Close();..。但不是分裂的:
System.IO.IOException: "File CRC Error"由于这里没有文件,我想知道
unrar.ReadHeader()以继续处理拆分存档的下一个文件发布于 2020-05-05 09:28:52
unrardll中包含的c#包装器和示例已经过时,不能很好地处理多卷rar文件,因为有新的回调消息无法处理。要修复它,请更改:
private enum CallbackMessages : uint
{
VolumeChange = 0,
ProcessData = 1,
NeedPassword = 2
}至
private enum CallbackMessages : uint
{
VolumeChange=0,
ProcessData=1,
NeedPassword=2,
VolumeChangeW = 3,
NeedPasswordW = 4,
}并处理VolumeChangeW的新回调消息:
private int RARCallback(uint msg, int UserData, IntPtr p1, int p2)
{
string volume=string.Empty;
string newVolume=string.Empty;
int result=-1;
switch((CallbackMessages)msg)
{
case CallbackMessages.VolumeChange:
case CallbackMessages.VolumeChangeW:
if ((CallbackMessages)msg == CallbackMessages.VolumeChange)
volume =Marshal.PtrToStringAnsi(p1);
else
volume = Marshal.PtrToStringAuto(p1);
if ((VolumeMessage)p2==VolumeMessage.Notify)
result=OnNewVolume(volume);
else if((VolumeMessage)p2==VolumeMessage.Ask)
{
newVolume=OnMissingVolume(volume);
if(newVolume.Length==0)
result=-1;
else
{
if(newVolume!=volume)
{
for(int i=0; i<newVolume.Length; i++)
{
Marshal.WriteByte(p1, i, (byte)newVolume[i]);
}
Marshal.WriteByte(p1, newVolume.Length, (byte)0);
}
result=1;
}
}
break;
case CallbackMessages.ProcessData:
result=OnDataAvailable(p1, p2);
break;
case CallbackMessages.NeedPassword:
result=OnPasswordRequired(p1, p2);
break;
default:
break;
}
return result;
}发布于 2021-08-08 21:45:27
我偶然发现了这个问题,希望能找到我所有问题的答案。但我找到了我的解决方案并愿意分享。
如果使用Unrar中的C#示例,则应该删除ProcessFileError()中的IOException("File CRC Error")或抛出错误。如果您在读取模式下打开文件,那么文件打开错误也是一样的。如果continuedOnNext == false.
case RARError.BadData:
if (!currentFile.continuedOnNext) throw new IOException("File CRC Error");
else break;下一个文件将是完全相同的文件名,并将成功提取(假设第2部分中的文件没有损坏)。请注意,如果列出新文件,则需要在ReadHeader()中修改此语句
// Determine if new file
if (((header.Flags & 0x01) != 0) && currentFile != null)
currentFile.ContinuedFromPrevious = true;对此:
// Determine if new file
if ((header.Flags & 0x01) != 0) return true;如果不想停止while循环,则希望返回true。
通常,如何确定拆分存档的第一个文件
如果您的意思是如何确定归档是否是第一个卷,则应该将Unrar.cs,archiveFlags中的私有属性更改为更容易访问的修饰符(例如:内部或公共)。
若要检查它是否为卷/拆分存档,请执行以下操作:
bool isVolume = (RARObj.archiveFlags & RAR.ArchiveFlags.Volume) == RAR.ArchiveFlags.Volume要检查它是否是第一个卷/拆分存档:
bool isFirstVolume = (RARObj.archiveFlags & RAR.ArchiveFlags.FirstVolume) == RAR.ArchiveFlags.FirstVolume如何确定整个提取过程的进度(以便在运行时在我的程序中输出进度)
您可以使用ListFiles获取归档文件计数,并将其用作主存档提取过程。然后提取并为RARObj.ExtractionProgress创建一个事件,以更新您拥有的任何ProgressBar。
ExtractionProgressEventArgs e为您提供了用于更新进度条的属性PercentComplete。我建议您分析一下WinRAR应用程序是如何做到的,这样您就可以更好地了解它是如何工作的。
还有一件事。
RAR RARObj = new Unrar(archive.path);发布于 2020-01-06 16:53:09
解决方案:
基本上,它与@Viezevingertjes在上面的注释中建议的SharpCompress一起工作。但不幸的是,SharpCompress还不支持RAR5解密,这意味着根本不提取RAR5密码保护的文件,因此SharpCompress的使用有限。
作为解决办法,您只能通过这样的进程调用直接使用rar.exe、unrar.exe或winrar.exe:
string rarExec = "\"c:\\Program Files\\WinRAR\\Rar.exe\"";
string sourceRar = "\"c:\\sourceFolder\\myfile.part001.rar\"";
string targetPath = "\"c:\\destinationFolder\"";
string password = "topsecret";
using (System.Diagnostics.Process process = new System.Diagnostics.Process())
{
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = rarExec;
if (password != "")
process.StartInfo.Arguments = "/c x -cfg- -inul -y " + "-p" + password + sourceRar + " " + targetPath;
else
process.StartInfo.Arguments = "/c x -cfg- -inul -y " + sourceRar + " " + targetPath;
process.Start();
process.WaitForExit();
switch (process.ExitCode)
{
case 0:
// "OK: extracted";
break;
case 10:
// "Error: wrong password";
break;
default:
// "Error: unknown";
break;
}
}https://stackoverflow.com/questions/59576125
复制相似问题