zoukankan      html  css  js  c++  java
  • 7z 程序打包 Demo

    最近准备做一个用户端 异常收集的程序  需要收集用户机器的程序日志和相关信息 准备打包发回来  所以研究了一下7Z 文件压缩 做一个笔记吧

    遇到的问题:

    1:VS2008 遇到 loadlibrary 以后显示  ERROR 6034

    解决方案

    #pragma comment(linker,"/manifestdependency:"type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'"")

    2:根据源码 没编译对正确的7z.dll

    最终使用的是 7z920.tarCPP7zipBundlesFormat7zF  里面编译的7z.dll

    攻略:

    编译DLL 的方式 

    由于 可以使用VS 也可以使用makefile

    makefile 使用方法:1启动VS2008命令行工具 并切换到对应目录  执行 nmake 等待即可

    代码demo

    由于只用到压缩 就不贴解压代码了

    源码自带Demo  目录 7z920.tarCPP7zipUIClient7z

    源码分析:

     入参:打包的文件信息列表 和目标包的 路径

    DWORD ArchiveFile(CObjectVector<CDirItem> &dirItems,LPCWSTR ArchivePackPath)
    {
        NT_CHECK
    
        NWindows::NDLL::CLibrary lib;
        if (!lib.Load(TEXT(kDllName)))//加载7z.dll
        {
            PrintError("Can not load 7-zip library");
            return 1;
        }
        CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");//获取COM 接口
        if (createObjectFunc == 0)
        {
            PrintError("Can not get CreateObject");
            return 1;
        }
    
        UString archiveName=ArchivePackPath;//打包后的位置    //保存打包位置
    
    
        COutFileStream *outFileStreamSpec = new COutFileStream;
        CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
        if (!outFileStreamSpec->Create(archiveName, true))//创建 打包文件
        {
            PrintError("can't create archive file");
            return 1;
        }
    
        CMyComPtr<IOutArchive> outArchive;    //取IOUTARCHIVE 接口
        if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)
        {
            PrintError("Can not get class object");
            return 1;
        }
        
        CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;        //压缩时 会调用的回调函数 
        CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
        updateCallbackSpec->Init(&dirItems);
    
        HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
        updateCallbackSpec->Finilize();            //压缩
        
        if (result != S_OK)
        {
            PrintError("Update Error");
            return 1;
        }
        for (int i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)    //打印失败文件
        {
            PrintNewLine();
            PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
        }
        if (updateCallbackSpec->FailedFiles.Size() != 0)//判断有几个失败的文件
            return 1;
        return 1;
    }

    打包文件的获取 我自己封装了一下 又以下2种方式

    一种是 打包一个文件夹 一种是通过一个文件名全路径的list 打包

     VOID GetArchiveItemFromPath(LPCTSTR strDirPath,CObjectVector<CDirItem> &dirItems)
    {
    
        NFile::NFind::CFileInfo fi;
        NFile::NFind::CFindFile TEST;
        AString dirPath;
        dirPath=strDirPath;
        dirPath+="\*.*";
         TEST.FindFirst(dirPath,fi);
         while(TEST.FindNext(fi))
         {
            if (fi.IsDots())
            {
                continue;
            }
             CDirItem di;
             di.Attrib = fi.Attrib;
             di.Size = fi.Size;
             di.CTime = fi.CTime;
             di.ATime = fi.ATime;
             di.MTime = fi.MTime;
             di.Name = MultiByteToUnicodeString(fi.Name);
            di.FullPath = MultiByteToUnicodeString(strDirPath);
            di.FullPath+=MultiByteToUnicodeString("\");
            di.FullPath+=MultiByteToUnicodeString(fi.Name);
             dirItems.Add(di);
         }
    }
    DWORD GetArchiveItemFromFileList(CObjectVector<AString> FileList,CObjectVector<CDirItem> &ItemList)
    {
    NFile::NFind::CFileInfo fi;
    for (int i=0;i<FileList.Size();i++)
    {
        if (fi.Find(FileList[i]))
        {
            CDirItem di;
            di.Attrib = fi.Attrib;
            di.Size = fi.Size;
            di.CTime = fi.CTime;
            di.ATime = fi.ATime;
            di.MTime = fi.MTime;
            di.Name = MultiByteToUnicodeString(fi.Name);
            di.FullPath = MultiByteToUnicodeString(FileList[i]);
            ItemList.Add(di);
        }
    }
    return 1;
    }
    //example
    /*
    CObjectVector<CDirItem> ItemList;
    GetArchiveItemFromPath("C:\Users\kr\Desktop\VPN",ItemList);
    ArchiveFile(ItemList,L"dirPath.7Z");
    
    CObjectVector<CDirItem> ItemList;
    CObjectVector<AString> fileList;
    fileList.Add("C:\Users\kr\Desktop\VPN\VPN.txt");
    fileList.Add("C:\Users\kr\Desktop\VPN.txt");
    fileList.Add("C:\Users\kr\Desktop\VPN\VPN3.txt");
    GetArchiveItemFromFileList(fileList,ItemList);
    ArchiveFile(ItemList,L"File.7Z");
    */
  • 相关阅读:
    studyframe项目总结
    js三级联动
    ajax提交,获取后台数据
    密码验证
    产生验证码
    使用泛型 ,做计算器
    web前端,css
    VS快捷键
    我的未来编码规范
    如何将CAJ文档转化为doc文档
  • 原文地址:https://www.cnblogs.com/FCoding/p/3531124.html
Copyright © 2011-2022 走看看