使用c++解压rar文件,基于UnRAR64,非命令行

最近项目需要解压缩rar文件,我们都知道rar是闭源收费软件,如果直接采用命令行可能会有限制,或者盗版问题,使用正版的winrar命令行解压rar文件是否有限制,这个我没来得及测试,但是从交互体验上来说,命令行对于很多情况的处理也不太友好,比如是否出错,比如异常处理,甚至某些高级功能,比如自定义解压缩的文件名等等,这些在命令行中不太好实现甚至无法实现。

网上很多关于c++解压rar的代码都是基于命令行的,这不是我想要的。

我想找能够解压rar的库或者dll,经过一番寻找,发现rarlab官网已经提供了UnRAR64,可以直接下载运行,这里提供一下下载地址:https://www.rarlab.com/rar/unrardll-624.exeicon-default.png?t=N7T8https://www.rarlab.com/rar/unrardll-624.exe

其他版本在这个页面:WinRAR archiver, a powerful tool to process RAR and ZIP filesicon-default.png?t=N7T8https://www.rarlab.com/rar_add.htm

使用官方的例子,即可实现winrar的解压缩,不过为了方便使用,我拓展了一下官方的代码,可以实现列出文件和解压缩rar文件到指定的目录,修改比较简单,这里直接上代码:

#pragma once#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <vector>#include "unrar.h"enum { EXTRACT, TEST, PRINT, LIST };int CommandLine(int Argc, char *Argv[]);void ExtractArchive(char *ArcName,int Mode);
void ExtractArchive(char *ArcName, char* DstDir);
void ListArchive(char *ArcName);
size_t ListArchive(char *ArcName, std::vector<std::string>& vFiles);
void ShowComment(wchar_t *CmtBuf);
void OutHelp(void);enum ERR_TYPE {ERR_OPEN, ERR_READ, ERR_PROCESS};
void OutError(int Error,char *ArcName,int ErrType);void ShowArcInfo(unsigned int Flags,char *ArcName);
void PrintTime(const char *Label,unsigned int Low,unsigned int High);
void OutProcessFileError(int Error);
int CALLBACK CallbackProc(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2);

实现文件:

#define STRICT#include "UnRDLL.h"int CommandLine(int Argc, char *Argv[])
{setlocale(LC_ALL, NULL);if (Argc!=3){OutHelp();return(0);}switch(toupper(Argv[1][0])){case 'X':ExtractArchive(Argv[2],EXTRACT);break;case 'T':ExtractArchive(Argv[2],TEST);break;case 'P':ExtractArchive(Argv[2],PRINT);break;case 'L':ListArchive(Argv[2]);break;default:OutHelp();return(0);}return(0);
}void ExtractArchive(char *ArcName,int Mode)
{HANDLE hArcData;int RHCode,PFCode;wchar_t CmtBuf[16384];struct RARHeaderData HeaderData;struct RAROpenArchiveDataEx OpenArchiveData;memset(&HeaderData,0,sizeof(HeaderData));memset(&OpenArchiveData,0,sizeof(OpenArchiveData));OpenArchiveData.ArcName=ArcName;OpenArchiveData.CmtBufW=CmtBuf;OpenArchiveData.CmtBufSize=sizeof(CmtBuf)/sizeof(CmtBuf[0]);OpenArchiveData.OpenMode=RAR_OM_EXTRACT;OpenArchiveData.Callback=CallbackProc;OpenArchiveData.UserData=Mode;hArcData=RAROpenArchiveEx(&OpenArchiveData);if (OpenArchiveData.OpenResult!=0){OutError(OpenArchiveData.OpenResult,ArcName,ERR_OPEN);return;}ShowArcInfo(OpenArchiveData.Flags,ArcName);if (OpenArchiveData.CmtState==1)ShowComment(CmtBuf);while ((RHCode=RARReadHeader(hArcData,&HeaderData))==0){switch(Mode){case EXTRACT:printf("\nExtracting %-45s",HeaderData.FileName);break;case TEST:printf("\nTesting %-45s",HeaderData.FileName);break;case PRINT:printf("\nPrinting %-45s\n",HeaderData.FileName);break;}PFCode=RARProcessFile(hArcData,(Mode==EXTRACT) ? RAR_EXTRACT:RAR_TEST,NULL,NULL);if (PFCode==0)printf(" OK");else{OutError(PFCode,ArcName,ERR_PROCESS);break;}}OutError(RHCode,ArcName,ERR_READ);RARCloseArchive(hArcData);
}void ExtractArchive(char *ArcName, char* DstDir)
{HANDLE hArcData;int RHCode,PFCode;wchar_t CmtBuf[16384];struct RARHeaderData HeaderData;struct RAROpenArchiveDataEx OpenArchiveData;memset(&HeaderData,0,sizeof(HeaderData));memset(&OpenArchiveData,0,sizeof(OpenArchiveData));OpenArchiveData.ArcName=ArcName;OpenArchiveData.CmtBufW=CmtBuf;OpenArchiveData.CmtBufSize=sizeof(CmtBuf)/sizeof(CmtBuf[0]);OpenArchiveData.OpenMode=RAR_OM_EXTRACT;OpenArchiveData.Callback=CallbackProc;OpenArchiveData.UserData= EXTRACT;hArcData=RAROpenArchiveEx(&OpenArchiveData);if (OpenArchiveData.OpenResult!=0){OutError(OpenArchiveData.OpenResult,ArcName,ERR_OPEN);return;}ShowArcInfo(OpenArchiveData.Flags,ArcName);if (OpenArchiveData.CmtState==1)ShowComment(CmtBuf);while ((RHCode=RARReadHeader(hArcData,&HeaderData))==0){printf("\nExtracting %-45s",HeaderData.FileName);PFCode=RARProcessFile(hArcData,RAR_EXTRACT,DstDir,NULL);if (PFCode==0)printf(" OK");else{OutError(PFCode,ArcName,ERR_PROCESS);break;}}OutError(RHCode,ArcName,ERR_READ);RARCloseArchive(hArcData);
}size_t ListArchive(char *ArcName, std::vector<std::string>& vFiles)
{HANDLE hArcData;int RHCode,PFCode;wchar_t CmtBuf[16384];struct RARHeaderDataEx HeaderData;struct RAROpenArchiveDataEx OpenArchiveData;wchar_t RedirName[1024];memset(&HeaderData,0,sizeof(HeaderData));memset(&OpenArchiveData,0,sizeof(OpenArchiveData));OpenArchiveData.ArcName=ArcName;OpenArchiveData.CmtBufW=CmtBuf;OpenArchiveData.CmtBufSize=sizeof(CmtBuf)/sizeof(CmtBuf[0]);OpenArchiveData.OpenMode=RAR_OM_LIST;OpenArchiveData.Callback=CallbackProc;OpenArchiveData.UserData=LIST;hArcData=RAROpenArchiveEx(&OpenArchiveData);if (OpenArchiveData.OpenResult!=0){OutError(OpenArchiveData.OpenResult,ArcName,ERR_OPEN);return 0;}ShowArcInfo(OpenArchiveData.Flags,ArcName);if (OpenArchiveData.CmtState==1)ShowComment(CmtBuf);HeaderData.RedirName=RedirName;HeaderData.RedirNameSize=sizeof(RedirName)/sizeof(RedirName[0]);while ((RHCode=RARReadHeaderEx(hArcData,&HeaderData))==0){__int64 UnpSize=HeaderData.UnpSize+(((__int64)HeaderData.UnpSizeHigh)<<32);__int64 PackSize=HeaderData.PackSize+(((__int64)HeaderData.PackSizeHigh)<<32);printf("\nName:   %s",HeaderData.FileName);vFiles.push_back(HeaderData.FileName);printf("\nSize:   %lld ",UnpSize);printf("\nPacked: %lld ",PackSize);PrintTime("mtime",HeaderData.MtimeLow,HeaderData.MtimeHigh);PrintTime("ctime",HeaderData.CtimeLow,HeaderData.CtimeHigh);PrintTime("atime",HeaderData.AtimeLow,HeaderData.AtimeHigh);if (HeaderData.RedirType!=0)printf("\n\tlink type %d, target %ls",HeaderData.RedirType,HeaderData.RedirName);if ((PFCode=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL))!=0){OutError(PFCode,ArcName,ERR_PROCESS);break;}printf("\n");}OutError(RHCode,ArcName,ERR_READ);RARCloseArchive(hArcData);return vFiles.size();
}void ListArchive(char *ArcName)
{HANDLE hArcData;int RHCode,PFCode;wchar_t CmtBuf[16384];struct RARHeaderDataEx HeaderData;struct RAROpenArchiveDataEx OpenArchiveData;wchar_t RedirName[1024];memset(&HeaderData,0,sizeof(HeaderData));memset(&OpenArchiveData,0,sizeof(OpenArchiveData));OpenArchiveData.ArcName=ArcName;OpenArchiveData.CmtBufW=CmtBuf;OpenArchiveData.CmtBufSize=sizeof(CmtBuf)/sizeof(CmtBuf[0]);OpenArchiveData.OpenMode=RAR_OM_LIST;OpenArchiveData.Callback=CallbackProc;OpenArchiveData.UserData=LIST;hArcData=RAROpenArchiveEx(&OpenArchiveData);if (OpenArchiveData.OpenResult!=0){OutError(OpenArchiveData.OpenResult,ArcName,ERR_OPEN);return;}ShowArcInfo(OpenArchiveData.Flags,ArcName);if (OpenArchiveData.CmtState==1)ShowComment(CmtBuf);HeaderData.RedirName=RedirName;HeaderData.RedirNameSize=sizeof(RedirName)/sizeof(RedirName[0]);while ((RHCode=RARReadHeaderEx(hArcData,&HeaderData))==0){__int64 UnpSize=HeaderData.UnpSize+(((__int64)HeaderData.UnpSizeHigh)<<32);__int64 PackSize=HeaderData.PackSize+(((__int64)HeaderData.PackSizeHigh)<<32);printf("\nName:   %s",HeaderData.FileName);printf("\nSize:   %lld ",UnpSize);printf("\nPacked: %lld ",PackSize);PrintTime("mtime",HeaderData.MtimeLow,HeaderData.MtimeHigh);PrintTime("ctime",HeaderData.CtimeLow,HeaderData.CtimeHigh);PrintTime("atime",HeaderData.AtimeLow,HeaderData.AtimeHigh);if (HeaderData.RedirType!=0)printf("\n\tlink type %d, target %ls",HeaderData.RedirType,HeaderData.RedirName);if ((PFCode=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL))!=0){OutError(PFCode,ArcName,ERR_PROCESS);break;}printf("\n");}OutError(RHCode,ArcName,ERR_READ);RARCloseArchive(hArcData);
}void ShowComment(wchar_t *CmtBuf)
{printf("\nComment:\n%ls\n",CmtBuf);
}void OutHelp(void)
{printf("\nUNRDLL.   This is a simple example of UNRAR.DLL usage\n");printf("\nSyntax:\n");printf("\nUNRDLL X <Archive>     extract archive contents");printf("\nUNRDLL T <Archive>     test archive contents");printf("\nUNRDLL P <Archive>     print archive contents to stdout");printf("\nUNRDLL L <Archive>     view archive contents\n");
}void OutError(int Error,char *ArcName,int ErrType)
{switch(Error){case ERAR_NO_MEMORY:printf("\nNot enough memory");break;case ERAR_BAD_DATA:printf("\n%s: archive header or data are damaged",ArcName);break;case ERAR_BAD_ARCHIVE:printf("\n%s is not RAR archive",ArcName);break;case ERAR_UNKNOWN_FORMAT:printf("Unknown archive format");break;case ERAR_EOPEN:if (ErrType==ERR_PROCESS) // Returned by RARProcessFile.printf("Volume open error");elseprintf("\nCannot open %s",ArcName);break;case ERAR_ECREATE:printf("File create error");break;case ERAR_ECLOSE:printf("File close error");break;case ERAR_EREAD:printf("Read error");break;case ERAR_EWRITE:printf("Write error");break;case ERAR_SMALL_BUF:printf("Buffer for archive comment is too small, comment truncated");break;case ERAR_UNKNOWN:printf("Unknown error");break;case ERAR_MISSING_PASSWORD:printf("Password for encrypted file or header is not specified");break;case ERAR_EREFERENCE:printf("Cannot open file source for reference record");break;case ERAR_BAD_PASSWORD:printf("Wrong password is specified");break;}
}void ShowArcInfo(unsigned int Flags,char *ArcName)
{printf("\nArchive %s\n",ArcName);printf("\nVolume:\t\t%s",(Flags & 1) ? "yes":"no");printf("\nComment:\t%s",(Flags & 2) ? "yes":"no");printf("\nLocked:\t\t%s",(Flags & 4) ? "yes":"no");printf("\nSolid:\t\t%s",(Flags & 8) ? "yes":"no");printf("\nNew naming:\t%s",(Flags & 16) ? "yes":"no");printf("\nRecovery:\t%s",(Flags & 64) ? "yes":"no");printf("\nEncr.headers:\t%s",(Flags & 128) ? "yes":"no");printf("\nFirst volume:\t%s",(Flags & 256) ? "yes":"no or older than 3.0");printf("\n---------------------------\n");
}void PrintTime(const char *Label,unsigned int Low,unsigned int High)
{if (Low!=0 || High!=0){FILETIME ft;ft.dwLowDateTime=Low;ft.dwHighDateTime=High;SYSTEMTIME ust,st;FileTimeToSystemTime(&ft,&ust);SystemTimeToTzSpecificLocalTime(NULL,&ust,&st);printf("\n%s:  %u-%02u-%02u %02u:%02u:%02u,%03u",Label,st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);}
}int CALLBACK CallbackProc(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2)
{switch(msg){case UCM_CHANGEVOLUMEW:if (P2==RAR_VOL_ASK){printf("\n\nVolume %S is required\nPossible options:\n",(wchar_t *)P1);printf("\nEnter - try again");printf("\n'R'   - specify a new volume name");printf("\n'Q'   - quit");printf("\nEnter your choice: ");switch(toupper(getchar())){case 'Q':return(-1);case 'R':{wchar_t *eol;printf("\nEnter new name: ");fflush(stdin);// fgetws may fail to read non-English characters from stdin// in some compilers. In this case use something more// appropriate for Unicode input.fgetws((wchar_t *)P1,MAX_PATH,stdin);eol=wcspbrk((wchar_t *)P1,L"\r\n");if (eol!=NULL)*eol=0;}return(1);default:return(1);}}if (P2==RAR_VOL_NOTIFY)printf("\n  ... volume %S\n",(wchar_t *)P1);return(1);case UCM_PROCESSDATA:if (UserData==PRINT){fflush(stdout);fwrite((char *)P1,1,P2,stdout);fflush(stdout);}return(1);case UCM_NEEDPASSWORDW:{wchar_t *eol;printf("\nPassword required: ");// fgetws may fail to read non-English characters from stdin// in some compilers. In this case use something more appropriate// for Unicode input.fgetws((wchar_t *)P1,(int)P2,stdin);eol=wcspbrk((wchar_t *)P1,L"\r\n");if (eol!=NULL)*eol=0;}return(1);}return(0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/163642.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「Verilog学习笔记」位拆分与运算

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 1、寄存器的位是可以分开单独运算的&#xff0c;并不是一个输入就一定是一个数据&#xff0c;在很多情况下&#xff0c;一个输入既包括数据又包括地址等其他有效信息 2、需…

利用浩客无代码开发API集成客服系统,提升用户服务质量

【浩客简介】 浩客&#xff0c;是由十年 SaaS 表单产品「金数据」团队打造的新产品。它主要面向数字化系统的用户评价、反馈、调研、通知工具&#xff0c;特定时机、精准触达&#xff0c;帮助产品经理、用研、UX、运营&#xff0c;聆听用户心声&#xff0c;增强用户触达&#…

大数据商城人流数据分析与可视化 - python 大数据分析 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的基站数据分析与可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度…

Docker数据管理、网络与Cgroup资源限制

目录 一、Docker的数据管理 1、数据卷 2、数据卷容器 3、端口映射 4、容器互联 二、Docker网络 2.1Docker网络实现原理 2.2Docker 的网络模式 3.3网络模式详解&#xff1a; host模式 container模式 none模式 bridge模式 自定义网络 创建自定义网络 三、Cgroup资源…

如何在 Unbuntu 下安装配置 Apache Zookeeper

简介 Zookeeper 是 apache 基金组织下的项目&#xff0c;项目用于简单的监控和管理一组服务&#xff0c;通过简单的接口就可以集中协调一组服务&#xff0c;如配置管理&#xff0c;信息同步&#xff0c;命名&#xff0c;分布式协调。 准备工作 Ubuntu 23.04 或者 20.04访问…

初阶JavaEE(15)(Cookie 和 Session、理解会话机制 (Session)、实现用户登录网页、上传文件网页、常用的代码片段)

接上次博客&#xff1a;初阶JavaEE&#xff08;14&#xff09;表白墙程序-CSDN博客 Cookie 和 Session 你还记得我们之前提到的Cookie吗&#xff1f; Cookie是HTTP请求header中的一个属性&#xff0c;是一种用于在浏览器和服务器之间持久存储数据的机制&#xff0c;允许网站…

浅谈前端自定义VectorGrid矢量瓦片样式

目录 前言 一、VectorGrid相关API介绍 1、VectorGrid 2、 LayerStyles样式详解 二、样式自动配置 1、页面定义 2、地图及PBF瓦片引入 3、矢量瓦片样式定义 4、鼠标事件交互 三、最终效果 1、自定义样式展示 2、鼠标交互 总结 前言 在上一篇博客中&#xff0c;详细讲…

【验证码系列】Google验证码从数据训练到机器自动识别算法构建

文章目录 1. 写在前面2. CSCI级设计决策2.1. Google验证码突防关联2.2. Google验证码突防行为设计决策 3. Google验证码突防体系结构设计3.1. Google验证码突防部件3.1.2. Google验证码突防组成 3.2. Google验证码突防软件3.2.1. Google验证码突防软件体系结构3.2.2. Google验证…

如何实现Word文档中的书签双向定位

工作中&#xff0c;经常需要拟定合同&#xff0c;一般都有固定的模板&#xff0c;在特定的位置填写内容。通过zOffice编辑合同文件时&#xff0c;可以在模板需要填写的位置预设书签&#xff0c;配合zOffice SDK使用&#xff0c;利用zOffice书签双向定位的特性&#xff0c;更方便…

后端工程化 | SpringBoot 知识点

文章目录 [SpringBoot] 后端工程化1 需求2 开发流程3 RequestController 类&#xff08;操作类&#xff09;3.1 简单参数&#xff08;形参名和请求参数名一致&#xff09;3.2 简单参数&#xff08;形参名和请求参数名不一致&#xff09;3.3 复杂实体参数3.4 数组参数3.5 集合参…

【黑马程序员】SpringCloud——微服务

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、服务架构演变1. 单体架构2. 分布式架构2.1 服务治理 3. 微服务3.1 微服务结构3.2 微服务技术对比3.3 企业需求 二、SpringCloud兼容性 三、服务拆分及远程调…

【qemu逃逸】华为云2021-qemu_zzz

前言 虚拟机用户名&#xff1a;root 无密码 设备逆向 经过逆向分析&#xff0c;可得实例结构体大致结构如下&#xff1a; 其中 self 指向的是结构体本身&#xff0c;cpu_physical_memory_rw 就是这个函数的函数指针。arr 应该是 PCI 设备类结构体没啥用&#xff0c;就直接用…