C++ 调用7z SDK 解压

2024-03-06 23:32
文章标签 c++ sdk 调用 解压 7z

本文主要是介绍C++ 调用7z SDK 解压,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        7z SDK 解压编译后,可以用"C 模式"解压,也可以用"CPP 模式"。C可以在内存中解压,但是很多时候不成功,是由于malloc分配不到内存。CPP不用担心内存问题,但是它解压的时候占用CPU较高。

       代码:

// Test7z.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "Common/IntToString.h"
#include "Common/MyInitGuid.h"
#include "Common/StringConvert.h"#include "Windows/DLL.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/FileName.h"
#include "Windows/NtCheck.h"
#include "Windows/PropVariant.h"
#include "Windows/PropVariantConversions.h"#include "7Z/CPP/7zip/Common/FileStreams.h"#include "7Z/CPP/7zip/Archive/IArchive.h"#include "7Z/CPP/7zip/IPassword.h"
#include "7Z/CPP/7zip/MyVersion.h"// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);using namespace NWindows;typedef UINT32 (WINAPI * CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);void PrintString(const UString &s)
{printf("%s", (LPCSTR)GetOemString(s));
}
void PrintString(const AString &s)
{printf("%s", (LPCSTR)s);
}
void PrintNewLine()
{PrintString("\n");
}
void PrintStringLn(const AString &s)
{PrintString(s);PrintNewLine();
}
void PrintError(const AString &s)
{PrintNewLine();PrintString(s);PrintNewLine();
}static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
{NCOM::CPropVariant prop;RINOK(archive->GetProperty(index, propID, &prop));if (prop.vt == VT_BOOL){result = VARIANT_BOOLToBool(prop.boolVal);}else if (prop.vt == VT_EMPTY){result = false;}else{return E_FAIL;}return S_OK;
}
static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
{return IsArchiveItemProp(archive, index, kpidIsDir, result);
}static const wchar_t *kEmptyFileAlias = L"[Content]";//
// Archive Open callback classclass CArchiveOpenCallback: public IArchiveOpenCallback, public ICryptoGetTextPassword, public CMyUnknownImp
{
public:MY_UNKNOWN_IMP1(ICryptoGetTextPassword)STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);STDMETHOD(CryptoGetTextPassword)(BSTR *password);bool PasswordIsDefined;UString Password;CArchiveOpenCallback() : PasswordIsDefined(false) {}
};STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
{return S_OK;
}
STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
{return S_OK;
}
STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
{if (!PasswordIsDefined){// You can ask real password here from user// Password = GetPassword(OutStream);// PasswordIsDefined = true;PrintError("Password is not defined");return E_ABORT;}return StringToBstr(Password, password);
}//
// Archive Extracting callback classstatic const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";static const char *kTestingString    =  "Testing     ";
static const char *kExtractingString =  "Extracting  ";
static const char *kSkippingString   =  "Skipping    ";static const char *kUnsupportedMethod = "Unsupported Method";
static const char *kCRCFailed = "CRC Failed";
static const char *kDataError = "Data Error";
static const char *kUnknownError = "Unknown Error";class CArchiveExtractCallback: public IArchiveExtractCallback, public ICryptoGetTextPassword, public CMyUnknownImp
{
public:MY_UNKNOWN_IMP1(ICryptoGetTextPassword)// IProgressSTDMETHOD(SetTotal)(UInt64 size);STDMETHOD(SetCompleted)(const UInt64 *completeValue);// IArchiveExtractCallbackSTDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);STDMETHOD(PrepareOperation)(Int32 askExtractMode);STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);// ICryptoGetTextPasswordSTDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);private:CMyComPtr<IInArchive> _archiveHandler;UString _directoryPath;  // Output directoryUString _filePath;       // name inside arcvhiveUString _diskFilePath;   // full path to file on diskbool _extractMode;struct CProcessedFileInfo{FILETIME MTime;UInt32 Attrib;bool isDir;bool AttribDefined;bool MTimeDefined;} _processedFileInfo;COutFileStream *_outFileStreamSpec;CMyComPtr<ISequentialOutStream> _outFileStream;public:void Init(IInArchive *archiveHandler, const UString &directoryPath);UInt64 nFilesize;UInt64 NumErrors;bool PasswordIsDefined;UString Password;CArchiveExtractCallback() : PasswordIsDefined(false) {}
};void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)
{NumErrors = 0;_archiveHandler = archiveHandler;_directoryPath = directoryPath;NFile::NName::NormalizeDirPathPrefix(_directoryPath);
}STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
{nFilesize = size;return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * completeValue)
{printf("%.2f\n", static_cast<float>((float)(*completeValue) / (float)nFilesize * 100.0f));return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{*outStream = 0;_outFileStream.Release();{// Get NameNCOM::CPropVariant prop;RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));UString fullPath;if (prop.vt == VT_EMPTY){fullPath = kEmptyFileAlias;}else{if (prop.vt != VT_BSTR){return E_FAIL;}fullPath = prop.bstrVal;}_filePath = fullPath;}if (askExtractMode != NArchive::NExtract::NAskMode::kExtract){return S_OK;}{// Get AttribNCOM::CPropVariant prop;RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));if (prop.vt == VT_EMPTY){_processedFileInfo.Attrib = 0;_processedFileInfo.AttribDefined = false;}else{if (prop.vt != VT_UI4){return E_FAIL;}_processedFileInfo.Attrib = prop.ulVal;_processedFileInfo.AttribDefined = true;}}RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir));{// Get Modified TimeNCOM::CPropVariant prop;RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));_processedFileInfo.MTimeDefined = false;switch(prop.vt){case VT_EMPTY:{// _processedFileInfo.MTime = _utcMTimeDefault;break;}case VT_FILETIME:{_processedFileInfo.MTime = prop.filetime;_processedFileInfo.MTimeDefined = true;break;}default:{return E_FAIL;}}}{// Get SizeNCOM::CPropVariant prop;RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));bool newFileSizeDefined = (prop.vt != VT_EMPTY);UInt64 newFileSize;if (newFileSizeDefined){newFileSize = ConvertPropVariantToUInt64(prop);}}{// Create folders for fileint slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);if (slashPos >= 0){NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));}}UString fullProcessedPath = _directoryPath + _filePath;_diskFilePath = fullProcessedPath;if (_processedFileInfo.isDir){NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);}else{NFile::NFind::CFileInfoW fi;if (fi.Find(fullProcessedPath)){if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath)){PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);return E_ABORT;}}_outFileStreamSpec = new COutFileStream;CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS)){PrintString((UString)L"can not open output file " + fullProcessedPath);return E_ABORT;}_outFileStream = outStreamLoc;*outStream = outStreamLoc.Detach();}return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
{_extractMode = false;switch (askExtractMode){case NArchive::NExtract::NAskMode::kExtract:  _extractMode = true; break;};switch (askExtractMode){case NArchive::NExtract::NAskMode::kExtract:  PrintString(kExtractingString); break;case NArchive::NExtract::NAskMode::kTest:  PrintString(kTestingString); break;case NArchive::NExtract::NAskMode::kSkip:  PrintString(kSkippingString); break;};PrintString(_filePath);return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
{switch(operationResult){case NArchive::NExtract::NOperationResult::kOK:break;default:{NumErrors++;PrintString("     ");switch(operationResult){case NArchive::NExtract::NOperationResult::kUnSupportedMethod:PrintString(kUnsupportedMethod);break;case NArchive::NExtract::NOperationResult::kCRCError:PrintString(kCRCFailed);break;case NArchive::NExtract::NOperationResult::kDataError:PrintString(kDataError);break;default:PrintString(kUnknownError);}}}if (_outFileStream != NULL){if (_processedFileInfo.MTimeDefined){_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);}RINOK(_outFileStreamSpec->Close());}_outFileStream.Release();if (_extractMode && _processedFileInfo.AttribDefined){NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);}PrintNewLine();return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
{if (!PasswordIsDefined){// You can ask real password here from user// Password = GetPassword(OutStream);// PasswordIsDefined = true;PrintError("Password is not defined");return E_ABORT;}return StringToBstr(Password, password);
}//
// Archive Creating callback classstruct CDirItem
{UInt64 Size;FILETIME CTime;FILETIME ATime;FILETIME MTime;UString Name;UString FullPath;UInt32 Attrib;bool isDir() const {return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ;}
};class CArchiveUpdateCallback: public IArchiveUpdateCallback2, public ICryptoGetTextPassword2, public CMyUnknownImp
{
public:MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)// IProgressSTDMETHOD(SetTotal)(UInt64 size);STDMETHOD(SetCompleted)(const UInt64 *completeValue);// IUpdateCallback2STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);STDMETHOD(SetOperationResult)(Int32 operationResult);STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);public:CRecordVector<UInt64> VolumesSizes;UString VolName;UString VolExt;UString DirPrefix;const CObjectVector<CDirItem> *DirItems;bool PasswordIsDefined;UString Password;bool AskPassword;bool m_NeedBeClosed;UStringVector FailedFiles;CRecordVector<HRESULT> FailedCodes;CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};~CArchiveUpdateCallback() { Finilize(); }HRESULT Finilize();void Init(const CObjectVector<CDirItem> *dirItems){DirItems = dirItems;m_NeedBeClosed = false;FailedFiles.Clear();FailedCodes.Clear();}
};STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */)
{return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)
{return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
{return E_NOTIMPL;
}
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
{if (newData != NULL){*newData = BoolToInt(true);}if (newProperties != NULL){*newProperties = BoolToInt(true);}if (indexInArchive != NULL){*indexInArchive = (UInt32)-1;}return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{NWindows::NCOM::CPropVariant prop;if (propID == kpidIsAnti){prop = false;prop.Detach(value);return S_OK;}{const CDirItem &dirItem = (*DirItems)[index];switch(propID){case kpidPath:  prop = dirItem.Name; break;case kpidIsDir:  prop = dirItem.isDir(); break;case kpidSize:  prop = dirItem.Size; break;case kpidAttrib:  prop = dirItem.Attrib; break;case kpidCTime:  prop = dirItem.CTime; break;case kpidATime:  prop = dirItem.ATime; break;case kpidMTime:  prop = dirItem.MTime; break;}}prop.Detach(value);return S_OK;
}HRESULT CArchiveUpdateCallback::Finilize()
{if (m_NeedBeClosed){PrintNewLine();m_NeedBeClosed = false;}return S_OK;
}static void GetStream2(const wchar_t *name)
{PrintString("Compressing  ");if (name[0] == 0){name = kEmptyFileAlias;}PrintString(name);
}STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{RINOK(Finilize());const CDirItem &dirItem = (*DirItems)[index];GetStream2(dirItem.Name);if (dirItem.isDir()){return S_OK;}{CInFileStream *inStreamSpec = new CInFileStream;CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);UString path = DirPrefix + dirItem.FullPath;if (!inStreamSpec->Open(path)){DWORD sysError = ::GetLastError();FailedCodes.Add(sysError);FailedFiles.Add(path);// if (systemError == ERROR_SHARING_VIOLATION){PrintNewLine();PrintError("WARNING: can't open file");// PrintString(NError::MyFormatMessageW(systemError));return S_FALSE;}// return sysError;}*inStream = inStreamLoc.Detach();}return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)
{m_NeedBeClosed = true;return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
{if (VolumesSizes.Size() == 0){return S_FALSE;}if (index >= (UInt32)VolumesSizes.Size()){index = VolumesSizes.Size() - 1;}*size = VolumesSizes[index];return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{wchar_t temp[16];ConvertUInt32ToString(index + 1, temp);UString res = temp;while (res.Length() < 2){res = UString(L'0') + res;}UString fileName = VolName;fileName += L'.';fileName += res;fileName += VolExt;COutFileStream *streamSpec = new COutFileStream;CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);if (!streamSpec->Create(fileName, false)){return ::GetLastError();}*volumeStream = streamLoc.Detach();return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{if (!PasswordIsDefined){if (AskPassword){// You can ask real password here from user// Password = GetPassword(OutStream);// PasswordIsDefined = true;PrintError("Password is not defined");return E_ABORT;}}*passwordIsDefined = BoolToInt(PasswordIsDefined);return StringToBstr(Password, password);
}//
// Main function#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;int MY_CDECL main(int numArgs, const char *args[])
{NT_CHECKint mmm = 0;while(mmm++ < 1){NWindows::NDLL::CLibrary lib;if (!lib.Load(L"7zxr.dll")){PrintError("Can not load 7-zip library");return 1;}CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");if (createObjectFunc == 0){PrintError("Can not get CreateObject");return 1;}char c = 'x';UString archiveName = GetUnicodeString("E:\\123.7z");{bool listCommand;if (c == 'l'){listCommand = true;}else if (c == 'x'){listCommand = false;}else{PrintError("incorrect command");return 1;}CMyComPtr<IInArchive> archive;if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK){PrintError("Can not get class object");return 1;}CInFileStream *fileSpec = new CInFileStream;CMyComPtr<IInStream> file = fileSpec;if (!fileSpec->Open(archiveName)){PrintError("Can not open archive file");return 1;}{CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);openCallbackSpec->PasswordIsDefined = false;// openCallbackSpec->PasswordIsDefined = true;// openCallbackSpec->Password = L"1";if (archive->Open(file, 0, openCallback) != S_OK){PrintError("Can not open archive");return 1;}}if (listCommand){// List commandUInt32 numItems = 0;archive->GetNumberOfItems(&numItems);for (UInt32 i = 0; i < numItems; i++){{// Get uncompressed size of fileNWindows::NCOM::CPropVariant prop;archive->GetProperty(i, kpidSize, &prop);UString s = ConvertPropVariantToString(prop);//PrintString(s);//PrintString("  ");}{// Get name of fileNWindows::NCOM::CPropVariant prop;archive->GetProperty(i, kpidPath, &prop);UString s = ConvertPropVariantToString(prop);//PrintString(s);}//PrintString("\n");}}else{// Extract commandCArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);extractCallbackSpec->Init(archive, L"e:\\XSBDownload"); // second parameter is output folder pathextractCallbackSpec->PasswordIsDefined = false;// extractCallbackSpec->PasswordIsDefined = true;// extractCallbackSpec->Password = L"1";HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);if (result != S_OK){PrintError("Extract Error");return 1;}}}}return 0;
}



demo:http://download.csdn.net/download/sz76211822/10039869

这篇关于C++ 调用7z SDK 解压的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/781713

相关文章

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

Java调用Python脚本实现HelloWorld的示例详解

《Java调用Python脚本实现HelloWorld的示例详解》作为程序员,我们经常会遇到需要在Java项目中调用Python脚本的场景,下面我们来看看如何从基础到进阶,一步步实现Java与Pyth... 目录一、环境准备二、基础调用:使用 Runtime.exec()2.1 实现步骤2.2 代码解析三、

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制

Python用Flask封装API及调用详解

《Python用Flask封装API及调用详解》本文介绍Flask的优势(轻量、灵活、易扩展),对比GET/POST表单/JSON请求方式,涵盖错误处理、开发建议及生产环境部署注意事项... 目录一、Flask的优势一、基础设置二、GET请求方式服务端代码客户端调用三、POST表单方式服务端代码客户端调用四

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c