在编写自主压缩解压软件FiveStarZip时,使用unrar.dll解压rar分卷文件时遇到总是报错问题,研究了一下,发现了问题。
原来unrar.dll应用的示例文件里的回调函数是这样:
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:
volume=Marshal.PtrToStringAnsi(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;
}
return result;
}
但是这样的话,测试过,不能产生Change Volume消息,所以当分卷时,到新卷时就会报错。
把代码改成这样,就能实现分卷解压缩了。
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.ProcessData:
result = OnDataAvailable(p1, p2);
break;
case CallbackMessages.NeedPassword:
result = OnPasswordRequired(p1, p2);
break;
default:
volume = Marshal.PtrToStringAnsi(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;
}
return result;
}
希望用到unrar.dll的程序员同学们,试试这样能不能起作用用了。
欢迎有不同意见的程序员同学们,提出宝贵意见。
注意:本文归作者所有,未经作者允许,不得转载