首页
http://www.7-zip.org/
下载地址
http://www.7-zip.org/download.html
选择7-Zip Source code
一栏的 Download,
我下载的是7z1602-src.7z
将下载的包解压,进入7z1602-src\C\Util\7z
目录,会看见一个7z.dsw
的vc6的工程项目,用自己当前vs版本打开,直接升级即可。
这个工程会生成一个7zDec.exe的可执行程序,它提供了只针对7z格式文件简单的解压缩功能(正好满足我的需求),解压算法采用的是LZMA。
LZMA是7z程序对7z格式文件默认的压缩算法,LZMA提供了高压缩率和非常快的解压速度。
注意事项:可能对中文路径支持有问题,且不支持加密文件等其它高级特性
打开工程后,先将项目的类型改为lib,在7z1602-src\C\Util\7z\7zMain.c
文件中新增extract_7z
函数
/*
pSrcFile : .7z文件名(可包含路径)
pDstPath : 解压至目标文件夹(必须用绝对路径,目录必须存在,如果为空,直接解压到当前目录)
*/
int MY_CDECL extract_7z(char* pSrcFile, wchar_t* pDstPath) {
int useDestPath = 0;
if (pSrcFile == NULL)
{
return -1;
}
if (pDstPath)
{
useDestPath = 1;
wchar_t szDstPath[MAX_PATH] = { 0 };
wcscpy(szDstPath, pDstPath);
pDstPath = szDstPath;
PathAddBackslash(szDstPath);
if (!PathFileExists(pDstPath))
{
return -1;
}
}
CFileInStream archiveStream;
CLookToRead lookStream;
CSzArEx db;
SRes res;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
UInt16 *temp = NULL;
UInt16 *destPath = NULL;
size_t tempSize = 0;
size_t destSize = 0;
// UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
#if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE)
g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
#ifdef UNDER_CE
if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
#else
if (InFile_Open(&archiveStream.file, pSrcFile))
#endif
{
PrintError("can not open input file");
return 1;
}
FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False);
lookStream.realStream = &archiveStream.s;
LookToRead_Init(&lookStream);
CrcGenerateTable();
SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if (res == SZ_OK)
{
int listCommand = 0, testCommand = 0, fullPaths = 1;
if (res == SZ_OK)
{
UInt32 i;
/*
if you need cache, use these 3 variables.
if you use external function, you can make these variable as static.
*/
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
for (i = 0; i < db.NumFiles; i++)
{
size_t offset = 0;
size_t outSizeProcessed = 0;
// const CSzFileItem *f = db.Files + i;
size_t len;
unsigned isDir = SzArEx_IsDir(&db, i);
if (listCommand == 0 && isDir && !fullPaths)
continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
// len = SzArEx_GetFullNameLen(&db, i);
if (len > tempSize)
{
SzFree(NULL, temp);
tempSize = len;
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
if (!temp)
{
res = SZ_ERROR_MEM;
break;
}
}
SzArEx_GetFileNameUtf16(&db, i, temp);
/*
if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp)
{
res = SZ_ERROR_FAIL;
break;
}
*/
if (listCommand)
{
char attr[8], s[32], t[32];
UInt64 fileSize;
GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
fileSize = SzArEx_GetFileSize(&db, i);
UInt64ToStr(fileSize, s);
if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t);
else
{
size_t j;
for (j = 0; j < 19; j++)
t[j] = ' ';
t[j] = '\0';
}
printf("%s %s %10s ", t, attr, s);
res = PrintString(temp);
if (res != SZ_OK)
break;
if (isDir)
printf("/");
printf("\n");
continue;
}
fputs(testCommand ?
"Testing " :
"Extracting ",
stdout);
res = PrintString(temp);
if (res != SZ_OK)
break;
if (isDir)
printf("/");
else
{
res = SzArEx_Extract(&db, &lookStream.s, i,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
if (res != SZ_OK)
break;
}
if (!testCommand)
{
CSzFile outFile;
size_t processedSize;
size_t j;
UInt16 *name = (UInt16 *)temp;
if (useDestPath) {
SzFree(NULL, destPath);
destSize = wcslen(pDstPath);
destSize += tempSize;
destPath = (UInt16 *)SzAlloc(NULL, destSize* sizeof(destPath[0]));
if (!destPath)
{
res = SZ_ERROR_MEM;
break;
}
wcscpy(destPath, pDstPath);
wcscat(destPath, temp);
name = destPath + wcslen(pDstPath);
}
else
destPath = (UInt16 *)name;
for (j = 0; name[j] != 0; j++)
if (name[j] == '/')
{
if (fullPaths)
{
name[j] = 0;
MyCreateDir(destPath);
name[j] = CHAR_PATH_SEPARATOR;
}
else
destPath = name + j + 1;
}
if (isDir)
{
MyCreateDir(destPath);
printf("\n");
continue;
}
else if (OutFile_OpenUtf16(&outFile, destPath))
{
PrintError("can not open output file");
res = SZ_ERROR_FAIL;
break;
}
processedSize = outSizeProcessed;
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZ_ERROR_FAIL;
break;
}
if (File_Close(&outFile))
{
PrintError("can not close output file");
res = SZ_ERROR_FAIL;
break;
}
#ifdef USE_WINDOWS_FILE
if (SzBitWithVals_Check(&db.Attribs, i))
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
#endif
}
printf("\n");
}
IAlloc_Free(&allocImp, outBuffer);
}
}
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
if (useDestPath) {
SzFree(NULL, destPath);
}
File_Close(&archiveStream.file);
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}
if (res == SZ_ERROR_UNSUPPORTED)
PrintError("decoder doesn't support this archive");
else if (res == SZ_ERROR_MEM)
PrintError("can not allocate memory");
else if (res == SZ_ERROR_CRC)
PrintError("CRC error");
else
printf("\nERROR #%d\n", res);
return 1;
}
在引用此lib的工程中调用此函数即可
extern "C" int __cdecl extract_7z(char* pSrcFile, wchar_t* pDstPath);
void Extract7z() {
extract_7z("test.7z", L"D:\\1234");
}
https://blog.byneil.com/category/zip-7z/7zip/
http://www.cnblogs.com/davad/p/3578628.html