在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例常规C/C++编程 → 简单的7z压缩解压代码

简单的7z压缩解压代码

常规C/C++编程

下载此实例
  • 开发语言:C/C++
  • 实例大小:0.02M
  • 下载次数:13
  • 浏览次数:447
  • 发布时间:2020-11-18
  • 实例类别:常规C/C++编程
  • 发 布 人:zelh
  • 文件格式:.zip
  • 所需积分:2
 相关标签: 简单 代码 解压 压缩

实例介绍

【实例简介】
【实例截图】

【核心代码】

// Client7z.cpp

#include "StdAfx.h"

#include <stdio.h>
#include <string>
#include <shlobj.h>

#include "../../../Common/MyWindows.h"

#include "../../../Common/Defs.h"
#include "../../../Common/MyInitGuid.h"

#include "../../../Common/IntToString.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/PropVariantConv.h"

#include "../../Common/FileStreams.h"

#include "../../Archive/IArchive.h"

#include "../../IPassword.h"
#include "../../../../C/7zVersion.h"
#include "Client7z.h"
#ifdef _WIN32
HINSTANCE g_hInstance = 0;
#endif

// Tou can find the list of all GUIDs in Guid.txt file.
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}

#define CLSID_Format CLSID_CFormat7z
// #define CLSID_Format CLSID_CFormatXz

Func_CreateObject g_CreateObjectFunc = NULL;
Func_GetNumberOfFormats g_GetNumberOfFormats = NULL;
Func_GetHandlerProperty2 g_GetHandlerProperty2 = NULL;
Func_GetIsArc g_GetIsArc = NULL;
vector<CArcInfoEx> g_ArcInfo;

using namespace NWindows;
using namespace NFile;
using namespace NDir;

#define kDllName "7z.dll"
wstring g_strPsw;
static const char * const kCopyrightString =
  "\n"
  "7-Zip"
  " (" kDllName " client)"
  " " MY_VERSION
  " : " MY_COPYRIGHT_DATE
  "\n";

static const char * const kHelpString =
"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n"
"Examples:\n"
"  7zcl.exe a archive.7z f1.txt f2.txt  : compress two files to archive.7z\n"
"  7zcl.exe l archive.7z   : List contents of archive.7z\n"
"  7zcl.exe x archive.7z   : eXtract files from archive.7z\n";


LPREQUESTCALLBACK g_lpRequestCallback = NULL;

static void Convert_UString_to_AString(const UString &s, AString &temp)
{
  int codePage = CP_OEMCP;
  /*
  int g_CodePage = -1;
  int codePage = g_CodePage;
  if (codePage == -1)
    codePage = CP_OEMCP;
  if (codePage == CP_UTF8)
    ConvertUnicodeToUTF8(s, temp);
  else
  */
    UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
}

static FString CmdStringToFString(const char *s)
{
  return us2fs(GetUnicodeString(s));
}

static void Print(const char *s)
{
  fputs(s, stdout);
}

static void Print(const AString &s)
{
  Print(s.Ptr());
}

static void Print(const UString &s)
{
  AString as;
  Convert_UString_to_AString(s, as);
  Print(as);
}

static void Print(const wchar_t *s)
{
  Print(UString(s));
}

static void PrintNewLine()
{
  Print("\n");
}

static void PrintStringLn(const char *s)
{
  Print(s);
  PrintNewLine();
}

static void PrintError(const char *message)
{
  Print("Error: ");
  PrintNewLine();
  Print(message);
  PrintNewLine();
}

static void PrintError(const char *message, const FString &name)
{
  PrintError(message);
  Print(name);
}


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 * const kEmptyFileAlias = L"[Content]";


//////////////////////////////////////////////////////////////
// Archive Open callback class


class 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 )
{

	if (g_lpRequestCallback)
	{
		I7zOpenBack callback = { 0 };
		callback.nType = 1;
		memcpy(&callback.itotal, files, sizeof(unsigned long long int));
		g_lpRequestCallback(1, &callback);
	}
  return S_OK;
}

STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 *  files , const UInt64 *  bytes )
{
	
	if (g_lpRequestCallback)
	{
		I7zOpenBack callback = { 0 };
		callback.nType = 2;
		memcpy(&callback.icurrent, files, sizeof(unsigned long long int));
		g_lpRequestCallback(1, &callback);
	}
  return S_OK;
}
  
STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
{
  if (!PasswordIsDefined)
  {
	g_strPsw.clear();
	I7zOpenBack callback = { 0 };
	callback.nType = 3;
	callback.isPassword = true;
	g_lpRequestCallback(1, &callback);
	if (g_strPsw.length())
	{
		Password = g_strPsw.c_str();;
		PasswordIsDefined = true;
		return StringToBstr(Password, password);
	}
	else
	{
		PrintError("Password is not defined");
		return E_ABORT;
	}
  }
  return StringToBstr(Password, password);
}



static const char * const kIncorrectCommand = "incorrect command";

//////////////////////////////////////////////////////////////
// Archive Extracting callback class

static const char * const kTestingString    =  "Testing     ";
static const char * const kExtractingString =  "Extracting  ";
static const char * const kSkippingString   =  "Skipping    ";

static const char * const kUnsupportedMethod = "Unsupported Method";
static const char * const kCRCFailed = "CRC Failed";
static const char * const kDataError = "Data Error";
static const char * const kUnavailableData = "Unavailable data";
static const char * const kUnexpectedEnd = "Unexpected end of data";
static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
static const char * const kIsNotArc = "Is not archive";
static const char * const kHeadersError = "Headers Error";

I7zExpandBack g_Expandcallback = { 0 };



void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath)
{
	m_Handle = NULL;
	m_cancel = false;
	m_stop = false;
  NumErrors = 0;
  _archiveHandler = archiveHandler;
  _directoryPath = directoryPath;
  NName::NormalizeDirPathPrefix(_directoryPath);
}

STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64  size )
{
	if (g_lpRequestCallback)
	{
		I7zExpandBack Expandcallback = { 0 };
		Expandcallback.nType = 1;
		memcpy(&Expandcallback.itotal, &size, sizeof(unsigned long long int));
		g_lpRequestCallback(2, &Expandcallback);
	}
	if (m_stop)
	{
		WaitForSingleObject(m_Handle, INFINITE);
	}

	if (m_cancel)
		return 1;
	else
		return S_OK;
}

STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *  completeValue)
{
	if (g_lpRequestCallback)
	{
		I7zExpandBack Expandcallback = { 0 };
		Expandcallback.nType = 2;
		memcpy(&Expandcallback.icurrent, completeValue, sizeof(unsigned long long int));
		g_lpRequestCallback(2, &Expandcallback);
	}
	if (m_stop)
	{
		WaitForSingleObject(m_Handle, INFINITE);
	}

	if (m_cancel)
		return 1;
	else
		return S_OK;
}

STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
    ISequentialOutStream **outStream, Int32 askExtractMode)
{
  *outStream = 0;
  _outFileStream.Release();

  {
    // Get Name
    NCOM::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 Attrib
    NCOM::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 Time
    NCOM::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;
    }

  }
  {
    NCOM::CPropVariant prop;
    RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
    UInt64 newFileSize;
     ConvertPropVariantToUInt64(prop, newFileSize);
  }

  
  {
    int slashPos = _filePath.ReverseFind_PathSepar();
    if (slashPos >= 0)
      CreateComplexDir(_directoryPath   us2fs(_filePath.Left(slashPos)));
  }

  FString fullProcessedPath = _directoryPath   us2fs(_filePath);
  _diskFilePath = fullProcessedPath;

  if (_processedFileInfo.isDir)
  {
    CreateComplexDir(fullProcessedPath);
  }
  else
  {
    NFind::CFileInfo fi;
    if (fi.Find(fullProcessedPath))
    {
		if (_filePath.Len())
		{
			if (g_lpRequestCallback)
			{
				I7zExpandBack Expandcallback = { 0 };
				Expandcallback.nType = 3;
				Expandcallback.nIndex = index;
				m_index = index;
				wcscpy(Expandcallback.lpFilePath, fullProcessedPath);
				g_lpRequestCallback(2, &Expandcallback);
			}
		}
	  if (2 == nFileType)				//重命名
	  {
		  wstring strzipfile = fullProcessedPath;
		  strzipfile  = TEXT(".temp");
		  _wrename(fullProcessedPath.GetBuf(), strzipfile.c_str());
	  }
    }
	if (fi.Find(fullProcessedPath) && 3 == nFileType)
	{

	}
	else
	{
		_outFileStreamSpec = new COutFileStream;
		CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
		if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
		{
			PrintError("Can not open output file", fullProcessedPath);
			return E_ABORT;
		}
		_outFileStream = outStreamLoc;
		*outStream = outStreamLoc.Detach();
	}
  }
  if (m_stop)
  {
	  WaitForSingleObject(m_Handle, INFINITE);
  }

  if (m_cancel)
	  return 1;
  else
	  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:  Print(kExtractingString); break;
    case NArchive::NExtract::NAskMode::kTest:  Print(kTestingString); break;
    case NArchive::NExtract::NAskMode::kSkip:  Print(kSkippingString); break;
  };
  Print(_filePath);
  if (m_stop)
  {
	  WaitForSingleObject(m_Handle, INFINITE);
  }

  if (m_cancel)
	  return 1;
  else
	  return S_OK;
}


STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
{
  switch (operationResult)
  {
    case NArchive::NExtract::NOperationResult::kOK:
      break;
    default:
    {
      NumErrors  ;
      Print("  :  ");
      const char *s = NULL;
      switch (operationResult)
      {
        case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
          s = kUnsupportedMethod;
          break;
        case NArchive::NExtract::NOperationResult::kCRCError:
          s = kCRCFailed;
          break;
        case NArchive::NExtract::NOperationResult::kDataError:
          s = kDataError;
          break;
        case NArchive::NExtract::NOperationResult::kUnavailable:
          s = kUnavailableData;
          break;
        case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
          s = kUnexpectedEnd;
          break;
        case NArchive::NExtract::NOperationResult::kDataAfterEnd:
          s = kDataAfterEnd;
          break;
        case NArchive::NExtract::NOperationResult::kIsNotArc:
          s = kIsNotArc;
          break;
        case NArchive::NExtract::NOperationResult::kHeadersError:
          s = kHeadersError;
          break;
      }
      if (s)
      {
        Print("Error : ");
        Print(s);
      }
      else
      {
        char temp[16];
        ConvertUInt32ToString(operationResult, temp);
        Print("Error #");
        Print(temp);
      }
    }
  }

  if (_outFileStream)
  {
    if (_processedFileInfo.MTimeDefined)
      _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
    RINOK(_outFileStreamSpec->Close());
  }
  _outFileStream.Release();
  if (_extractMode && _processedFileInfo.AttribDefined)
    SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib);
  PrintNewLine();

  if (g_lpRequestCallback)
  {
	  I7zExpandBack ExpandBack = { 0 };
	  ExpandBack.nType = 4;
	  ExpandBack.nSuccess = operationResult;
	  ExpandBack.nIndex = m_index;
	  wcscpy(ExpandBack.lpFilePath, _filePath);
	  g_lpRequestCallback(2, &ExpandBack);
  }
  if (m_stop)
  {
	  WaitForSingleObject(m_Handle, INFINITE);
  }

  if (m_cancel)
	  return 1;
  else
	  return S_OK;
}


STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
{

	if (!PasswordIsDefined)
	{
		g_strPsw.clear();
		I7zExpandBack ExpandBack = { 0 };
		ExpandBack.nType = 5;
		ExpandBack.isPassword = true;
		g_lpRequestCallback(2, &ExpandBack);
		if (g_strPsw.length())
		{
			Password = g_strPsw.c_str();;
			PasswordIsDefined = true;
			return StringToBstr(Password, password);
		}
		else
		{
			PrintError("Password is not defined");
			return E_ABORT;
		}
	}
  return StringToBstr(Password, password);
}



//////////////////////////////////////////////////////////////
// Archive Creating callback class


class CArchiveUpdateCallback:
  public IArchiveUpdateCallback2,
  public ICryptoGetTextPassword2,
  public CMyUnknownImp
{
public:
  MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)

  // IProgress
  STDMETHOD(SetTotal)(UInt64 size);
  STDMETHOD(SetCompleted)(const UInt64 *completeValue);

  // IUpdateCallback2
  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;

  FString DirPrefix;
  const CObjectVector<CDirItem> *DirItems;

  bool PasswordIsDefined;
  UString Password;
  bool AskPassword;

  bool m_NeedBeClosed;

  FStringVector 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::GetUpdateItemInfo(UInt32  index ,
      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
{
  if (newData)
    *newData = BoolToInt(true);
  if (newProperties)
    *newProperties = BoolToInt(true);
  if (indexInArchive)
    *indexInArchive = (UInt32)(Int32)-1;
  return S_OK;
}

STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
  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)
{
  Print("Compressing  ");
  if (name[0] == 0)
    name = kEmptyFileAlias;
  Print(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);
    FString 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");
        // Print(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.Len() < 2)
    res.InsertAtFront(L'0');
  UString fileName = VolName;
  fileName  = '.';
  fileName  = res;
  fileName  = VolExt;
  COutFileStream *streamSpec = new COutFileStream;
  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
  if (!streamSpec->Create(us2fs(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);
}


bool __stdcall I7zOutArchive::SaveToFile(LPWSTR lpOutFilePath, unsigned int nSpeed = 1, bool isSFX = false, unsigned int nCount512K = 1)
{
	if (NULL == lpOutFilePath)
	{
		return false;
	}
	if (':' != lpOutFilePath[1])
	{
		return false;
	}
	SECURITY_ATTRIBUTES secattr = { 0 };
	secattr.nLength = sizeof(secattr);
	secattr.bInheritHandle = TRUE;


	HANDLE rPipe = NULL, wPipe = NULL;
	CreatePipe(&rPipe, &wPipe, &secattr, 0);

	shared_ptr<HANDLE> ptrHandler(&rPipe,handlecloser);
	shared_ptr<HANDLE> ptrHandlew(&wPipe, handlecloser);

	STARTUPINFO sInfo = { 0 };
	PROCESS_INFORMATION pInfo = { 0 };
	sInfo.cb = sizeof(sInfo);
	sInfo.dwFlags = STARTF_USESTDHANDLES;
	sInfo.hStdInput = NULL;
	sInfo.hStdOutput = wPipe;
	sInfo.hStdError = wPipe;


	wstring wsExecute;
	wsExecute  = TEXT("C:\\UTIL\\7z.exe   ");
	wsExecute  = TEXT("A \"C:\\qt-everywhere-src-51.zip\"  \"C:\\qt-everywhere-src-5.15.1.zip\" -v200m ");
	if (CreateProcessW(0, (LPWSTR)wsExecute.c_str(), 0, 0, TRUE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, 0, 0, &sInfo, &pInfo) != 0)
	{
		string m_csOutput;
		bool res = false;
		do
		{
			DWORD reDword;
			BYTE buf[100] = { 0 };
			res = ::ReadFile(rPipe, buf, 100, &reDword, 0);
			m_csOutput  = (char *)buf;
		} while (res);
		return true;
	}
	else
	{
		return false;
	}
}

bool __stdcall I7zOutArchive::SaveToFile(LPWSTR lpOutFilePath,LPWSTR LPFileType )
{

	if (NULL == lpOutFilePath)
	{
		return false;
	}
	if (':' != lpOutFilePath[1])
	{
		return false;
	}
	_wcslwr_s(LPFileType, wcslen(LPFileType)   1);
	if (!wcscmp(LPFileType, TEXT("7z"))&&
		!wcscmp(LPFileType, TEXT("zip"))&& 
		!wcscmp(LPFileType, TEXT("bz2"))&&
		!wcscmp(LPFileType, TEXT("xz"))&&
		!wcscmp(LPFileType, TEXT("tar"))&&
		!wcscmp(LPFileType, TEXT("gz"))&&
		!wcscmp(LPFileType, TEXT("wim")) )
	{
		return false;
	}

	vector<CLSID> vtr;
	for (auto itr = g_ArcInfo.begin();itr != g_ArcInfo.end();itr  )
	{
		wstring wstr = itr->Exts[LPFileType];
		if (wstr.length())
		{
			if (0 == itr->SignatureOffset)
			{
				vtr.push_back(itr->ClassID);
			}
		}
	}
	if (0 == vtr.size())
	{
		return false;
	}
	COutFileStream *outFileStreamSpec = new COutFileStream;
	CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
	if (!outFileStreamSpec->Create(lpOutFilePath, false))
	{
		PrintError("can't create archive file");
		return false;
	}
	CMyComPtr<IOutArchive> outArchive;
	if (g_CreateObjectFunc(&vtr[0], &IID_IOutArchive, (void **)&outArchive) != S_OK)
	{
		PrintError("Can not get class object");
		return false;
	}
	CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
	CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
	updateCallbackSpec->Init(&m_dirItems);
	if (0 == m_wstr.length())
	{
		updateCallbackSpec->PasswordIsDefined = false;
	}
	else
	{
		updateCallbackSpec->PasswordIsDefined = true;
		updateCallbackSpec->Password = m_wstr.c_str();
	}
	HRESULT result = outArchive->UpdateItems(outFileStream, m_dirItems.Size(), updateCallback);
	updateCallbackSpec->Finilize();
	m_dirItems.Clear();
	if (result != S_OK)
	{
		PrintError("Update Error");
		return false;
	}
	FOR_VECTOR(i, updateCallbackSpec->FailedFiles)
	{
		PrintNewLine();
		PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
	}

	if (updateCallbackSpec->FailedFiles.Size() != 0)
		return false;
	else
    	return true;
}


bool __stdcall I7zOutArchive::AddFile(LPWSTR lpFileName, LPWSTR lpFullPath)
{
	CDirItem di;
	FString name = lpFullPath;
	NFind::CFileInfo fi;
	if (!fi.Find(lpFullPath))
	{
		PrintError("Can't find file", name);
		return false;
	}
	di.Attrib = fi.Attrib;
	di.Size = fi.Size;
	di.CTime = fi.CTime;
	di.ATime = fi.ATime;
	di.MTime = fi.MTime;
	di.Name = lpFileName;
	di.FullPath = lpFullPath;
	m_dirItems.Add(di);
	return true;
}

void __stdcall I7zInArchive::ExtractCancel()
{
	m_extractCallbackSpec->m_cancel = true;
}
void __stdcall I7zInArchive::ExtractPause()
{
	m_extractCallbackSpec->m_stop = true;
	if (NULL == m_extractCallbackSpec->m_Handle)
	{
		m_extractCallbackSpec->m_Handle = CreateSemaphore(NULL, 0, 1, NULL); 
	}
}
void __stdcall I7zInArchive::ExtractStar()
{
	m_extractCallbackSpec->m_stop = false;
	ReleaseSemaphore(m_extractCallbackSpec->m_Handle, 1, NULL);
}


LPWSTR __stdcall I7zInArchive::GetItemCreateTime(unsigned int index)
{
	wchar_t wTemp[1024] = { 0 };
	NCOM::CPropVariant prop;
	m_archive->GetProperty(index, kpidCTime, &prop);
	SYSTEMTIME st = {0};
	FileTimeToLocalFileTime(&prop.filetime, &prop.filetime);
	FileTimeToSystemTime(&prop.filetime, &st);
	wsprintfW(wTemp,TEXT("%d-%d-%d  %d:%d"), st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute);
	return wTemp;
}
LPWSTR __stdcall I7zInArchive::GetItemModifyTime(unsigned int index)
{ 
	wchar_t wTemp[1024] = { 0 };
	NCOM::CPropVariant prop;
	m_archive->GetProperty(index, kpidMTime, &prop);
	SYSTEMTIME st = {0};
	FileTimeToLocalFileTime(&prop.filetime, &prop.filetime);
	FileTimeToSystemTime(&prop.filetime, &st);
	wsprintfW(wTemp, TEXT("%d-%d-%d  %d:%d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute);
	return wTemp;
}

bool __stdcall I7zInArchive::ExtractTo(LPWSTR lpOutPath,bool isTest = false)
{
	if (false == isTest)
	{
		if (NULL == lpOutPath)
			return false;
		if (':' != lpOutPath[1])
			return false;
		SHCreateDirectoryExW(NULL, lpOutPath, NULL);
	}
	m_extractCallbackSpec = new CArchiveExtractCallback;
	CMyComPtr<IArchiveExtractCallback> extractCallback(m_extractCallbackSpec);
	if(NULL == lpOutPath)
	   m_extractCallbackSpec->Init(m_archive, TEXT("C:\\text")); 
	else
		m_extractCallbackSpec->Init(m_archive, lpOutPath);

	m_extractCallbackSpec->nFileType = 3;
	m_extractCallbackSpec->PasswordIsDefined = false;
	if (0 == m_wstr.length())
	{
		m_extractCallbackSpec->PasswordIsDefined = false;
	}
	else
	{
		m_extractCallbackSpec->PasswordIsDefined = true;
		m_extractCallbackSpec->Password = m_wstr.c_str();
	}
	HRESULT result = m_archive->Extract(NULL, (UInt32)(Int32)(-1), isTest, extractCallback);
	if (NULL != m_extractCallbackSpec->m_Handle)
	{
		CloseHandle(m_extractCallbackSpec->m_Handle);
	}
	if (result != S_OK)
		return false;
	else
		return true;

}


bool __stdcall I7zInArchive::ExtractItems(unsigned int* nIndex, unsigned int nCount, LPWSTR lpOutPath)
{
	if (NULL == nIndex || nCount == 0)
		return false;
	if (NULL == lpOutPath)
		return false;
	if (':' != lpOutPath[1])
		return false;
	SHCreateDirectoryExW(NULL, lpOutPath, NULL);
	m_extractCallbackSpec = new CArchiveExtractCallback;
	m_extractCallbackSpec->nFileType = 1;
	CMyComPtr<IArchiveExtractCallback> extractCallback(m_extractCallbackSpec);
	m_extractCallbackSpec->Init(m_archive, lpOutPath); // second parameter is output folder path
	m_extractCallbackSpec->PasswordIsDefined = false;
	if (0 == m_wstr.length())
	{
		m_extractCallbackSpec->PasswordIsDefined = false;
	}
	else
	{
		m_extractCallbackSpec->PasswordIsDefined = true;
		m_extractCallbackSpec->Password = m_wstr.c_str();
	}
	HRESULT result = m_archive->Extract(nIndex, (UInt32)(Int32)nCount, false, extractCallback);
	if (NULL != m_extractCallbackSpec->m_Handle)
	{
		CloseHandle(m_extractCallbackSpec->m_Handle);
	}
	if (result != S_OK)
		return false;
	else
		return true;

}
void __stdcall I7zInArchive::SetFileType(int nType)
{
	if (m_extractCallbackSpec)
	{
		m_extractCallbackSpec->nFileType = nType;
	}
}
unsigned long long int  I7zInArchive::GetItemPackSize(unsigned int index)
{
	NCOM::CPropVariant prop;
	m_archive->GetProperty(index, kpidPackSize, &prop);
	return prop.uhVal.QuadPart;
}

bool I7zInArchive::GetItemIsFolder(unsigned int index)
{
	NCOM::CPropVariant prop;
	m_archive->GetProperty(index, kpidIsDir, &prop);
	return (bool)prop.boolVal;
}

unsigned long long int  I7zInArchive::GetItemSize(unsigned int index)
{
	NCOM::CPropVariant prop;
	m_archive->GetProperty(index, kpidSize, &prop);
	return prop.uhVal.QuadPart;
}

void I7zInArchive::GetNumberOfItems(unsigned int *numItems)
{
	m_archive->GetNumberOfItems(numItems);
}

LPWSTR I7zInArchive::GetItemPath(unsigned int index)
{
	NCOM::CPropVariant prop;
	m_archive->GetProperty(index, kpidPath, &prop);
	return (LPWSTR)prop.bstrVal;
}

void I7zInArchive::SetPassword(LPWSTR lppassword)
{
	m_wstr = lppassword;
	g_strPsw = lppassword;
	
}
bool I7zInArchive::OpenFile(CLSID vtr,LPWSTR szFileName)
{
	if (g_CreateObjectFunc(&vtr, &IID_IInArchive, (void **)&m_archive) != S_OK)
	{
		return false;
	}
	CInFileStream *fileSpec = new CInFileStream;
	CMyComPtr<IInStream> file = fileSpec;
	if (!fileSpec->Open(us2fs(szFileName)))
	{
		return false;
	}
//	UInt64 _arhiveBeginStreamPosition, _fileEndPosition;
//	fileSpec->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition);
//	fileSpec->Seek(0, STREAM_SEEK_END, &_fileEndPosition);
	CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
	CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
	if (0 == m_wstr.length())
	{
		openCallbackSpec->PasswordIsDefined = false;
	}
	else
	{
		openCallbackSpec->PasswordIsDefined = true;
		openCallbackSpec->Password = m_wstr.c_str();
	}
	const UInt64 scanSize =  1 << 23;
	if (m_archive->Open(file, &scanSize, openCallback) == S_OK)
	{
		m_isOpen = true;
		return true;
	}
	return false;
}
bool I7zInArchive::OpenFile(LPWSTR szFileName)
{
	wchar_t drive[10] = { 0 };
	wchar_t dir[256] = { 0 };
	wchar_t fname[256] = { 0 };
	wchar_t ext[256] = { 0 };
	wchar_t ext1[256] = { 0 };
	if (NULL == szFileName)
	{
		return false;
	}
	if (':' != szFileName[1])
	{
		return false;
	}
	::_wsplitpath_s(szFileName, drive, _MAX_DRIVE, dir, _MAX_DIR,fname, _MAX_FNAME, ext, _MAX_EXT);
	if ('.' == ext[0])
	{
//  		if ('0' == ext[1]&&  '0'== ext[2])
//  		{
//  			memcpy(ext1, PathFindExtensionW(fname)   1, 4);
//  		}
//  		else
//      	{
//  			memcpy(ext1, &ext[1], 10);
//  		}
		memcpy(ext1, &ext[1], 10);
		_wcslwr_s(ext1, wcslen(ext1)   1);
			
	}
	vector<CLSID> vtr;
	for (vector<CArcInfoEx>::iterator itr = g_ArcInfo.begin(); itr != g_ArcInfo.end();   itr)
	{
		wstring wstr = itr->Exts[ext1];
		if (wstr.length())
		{
			if (0 == wstr.compare(ext1))
			{
				vtr.push_back(itr->ClassID);
			}
		}
	}
	if (vtr.size())
	{
		if (true == OpenFile(vtr.at(0),szFileName))
		{
			return true;
		}
	}

	DWORD nSize = 0;
	BYTE *buf = NULL;
	DWORD dwBytes = 0;
	HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
		return false;
	DWORD dwsizehigh_src, dwsizelow_src;
	dwsizelow_src = GetFileSize(hFile, &dwsizehigh_src);
	if (dwsizehigh_src > 0 || dwsizelow_src > nSize)
	{
		nSize = 1048576;
	}
	else
	{
		nSize = dwsizelow_src;
	}
	buf = new BYTE[nSize];
	shared_ptr<BYTE> pbuf(buf);
	shared_ptr<HANDLE> ptr(&hFile, handlecloser);

	if (false == ReadFile(hFile, buf, nSize, &dwBytes, NULL))
		return false;
	for (vector<CArcInfoEx>::iterator itr1 = g_ArcInfo.begin(); itr1 != g_ArcInfo.end();   itr1)
	{
		const CObjectVector<CByteBuffer> &sigs = itr1->Signatures;
		for (int n = 0; n < itr1->Signatures.Size(); n  )
		{
			const CByteBuffer &sig = sigs[n];
			if (memcmp(sig, buf   itr1->SignatureOffset, sig.Size()) == 0)
			if (true == OpenFile(itr1->ClassID, szFileName))
			{
				return true;
			}
		}
	}
	return false;
}

bool InitModule()
{
	char szPath[256] = { 0 };
	CS_GetApplicationPath(szPath, 256, "7z.dll");
	HMODULE hlib = ::LoadLibraryA(szPath);
	if (NULL == hlib)
	{
		return false;
	}

	g_CreateObjectFunc = (Func_CreateObject)GetProcAddress(hlib, "CreateObject");
	if (!g_CreateObjectFunc)
		return false;
	g_GetNumberOfFormats = (Func_GetNumberOfFormats)GetProcAddress(hlib, "GetNumberOfFormats");
	if (!g_GetNumberOfFormats)
		return false;
	g_GetHandlerProperty2 = (Func_GetHandlerProperty2)GetProcAddress(hlib, "GetHandlerProperty2");
	if (!g_GetHandlerProperty2)
		return false;
	g_GetIsArc = (Func_GetIsArc)GetProcAddress(hlib, "GetIsArc");
	if (!g_GetIsArc)
		return false;
	vector<wstring> vExe, vaddExt;
	UInt32 numFormats = 0;
	g_GetNumberOfFormats(&numFormats);
	for (UInt32 i = 0; i < numFormats; i  )
	{
		NCOM::CPropVariant prop;
		CArcInfoEx item;
		item.FormatIndex = i;
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kName, &prop);
			if (prop.vt != VT_EMPTY)
			{
				item.wstrName = prop.bstrVal;
			}
		}
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kClassID, &prop);
			if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
				continue;
			item.ClassID = *(const GUID *)prop.bstrVal;
		}
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kExtension, &prop);
			if (prop.vt != VT_EMPTY)
			{
				SplitString(prop.bstrVal, vExe);
			}
		}
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kAddExtension, &prop);
			if (prop.vt != VT_EMPTY)
			{
				SplitString(prop.bstrVal, vaddExt);
			}
		}
		for (int n = 0; n < vExe.size(); n  )
		{
			if (n < vaddExt.size())
			{
				if (L"*" != vaddExt[n])
				{
					item.Exts[vExe.at(n)] = vaddExt.at(n);
					continue;
				}
			}
			item.Exts[vExe.at(n)] = vExe.at(n);
		}
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kUpdate, &prop);
			item.isUpdateEnabled = prop.boolVal;
		}
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kFlags, &prop);
			item.Flags = prop.ulVal;
		}
		{
			prop.Clear();
			CByteBuffer sig;
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kSignature, &prop);
			UINT len = ::SysStringByteLen(prop.bstrVal);
			if (len != 0)
				item.Signatures.AddNew().CopyFrom((const Byte *)prop.bstrVal, len);
			else
			{
				g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kMultiSignature, &prop);
				ParseSignatures((const Byte *)prop.bstrVal, (unsigned)SysStringByteLen(prop.bstrVal), item.Signatures);
			}
		}
		{
			prop.Clear();
			g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kSignatureOffset, &prop);
			item.SignatureOffset = prop.ulVal;
		}
		g_GetIsArc(i, &item.IsArcFunc);
		g_ArcInfo.push_back(item);
	}
	return true;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		if (false == InitModule())
			return false;
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

void __stdcall SetCallBack(LPREQUESTCALLBACK lpCallBack)
{
	g_lpRequestCallback = lpCallBack;
}

bool __stdcall GetI7zInArchiveClass(I7zInArchive*& i7z)
{
	i7z = new I7zInArchive;
	if (i7z)
		return true;
	else
		return false;
}

void __stdcall FreeClass(void* i7z)
{	
	//全部放入vector或者只能指针释放
	if (i7z)
	{
		delete i7z;
		i7z = NULL;
	}
}
bool __stdcall GetI7zOutArchiveClass(I7zOutArchive*& i7z)
{
	i7z = new I7zOutArchive;
	if (i7z)
		return true;
	else
		return false;
}
//{23170F69 - 40C1 - 278A - 1000 - 000110010000}
#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
int MY_CDECL main(int numArgs, const char *args[])
{
	InitModule();
	I7zInArchive* I7zIn = NULL;
	I7zOutArchive* I7zout = NULL;
	GetI7zInArchiveClass(I7zIn);
	//I7zIn->OpenFile(TEXT("C:\\qt-everywhere-src-5.15.1.zip"));
	//int i[10];
	//for (int n = 0; n<10;n  )
	//{
	//	i[n] = n;
	//}
	//I7zIn->ExtractItems((unsigned int*)&i, 10, TEXT("D:\\2222"));
	//I7zIn->OpenFile( TEXT("c:\\windows11111"));
	//I7zIn->ExtractTo(NULL,true);
	GetI7zOutArchiveClass(I7zout);
	I7zout->AddFile(TEXT("7-ZIP\\7zFM.exe"), TEXT("C:\\Program Files\\7-ZIP\\7zFM.exe"));
	I7zout->AddFile(TEXT("vscd1"), TEXT("C:\\迅雷下载\\vscd1"));
	I7zout->SaveToFile(TEXT("d:\\DriverTest_1.7z"), TEXT("7z"));
//	I7zout->SaveToFile(TEXT("C:\\Program Files\\7-ZIP\\7zFM.zip"), 1,false,1);

	return 0;
}
;

实例下载地址

简单的7z压缩解压代码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警