PB8调用使用C++与C#分别编写生成解压缩带有密码的zip压缩文件的动态链接库dll(部分内容转自互联网)

声明:本篇文章部分内容转自互联网,因为这些代码不能直接运行,本人对其略有修改。

C++使用zlib压缩和解压缩文件 http://download.csdn.net/download/yanghongche/5029259
C#使用 ICSharpCode.SharpZipLib.dll压缩解压缩 http://www.cnblogs.com/xuanye/archive/2011/10/19/2217211.html
 
C++开发工具使用的是VC++6.0,C#开发工具使用的是VS2012。
 
(一)、C++编写生成解压缩带有密码的zip压缩文件(使用zlib)的动态链接库dll
一、第一步:创建动态链接库工程
     1. 新建--工程--win32 dynamic-link library,输入工程名字unzip,确定,一个简单的dll工程,确定,确定。
     2. 新建--文件--c/c++ header file--文件名unzip,确定。
          该头文件里写以下代码:
#include "afx.h"
extern "C" _declspec(dllexport) int __stdcall UnzipFile(char* FilePath, char* TmpPath, char* Psd);
     3. stdafx.h头文件里却掉以下代码:
          #include <windows.h>
          若不去掉会报一下错误:fatal error C1189: #error :  WINDOWS.H already included.  MFC apps must not #include <windows.h>
     4. unzip.cpp里写入以下代码:
 // unzip.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "unzip.h"


#include<iostream>
#include<string>
#include "Shlwapi.h"

using  std::string;
using namespace std;

#include "zlib\unzip.h" 
#include "zlib\zlib.h" 
#include "zlib\zip.h" 
  
#pragma comment( lib, "zlib.lib" )    // 将静态库引用进来 
#pragma comment( lib, "minizip.lib" ) 
#pragma comment( lib, "Shlwapi.lib" ) 

#define ZIP_OPEN_FAILED    1 
#define ZIP_GETGLOBAL_FAILED  2 
#define ZIP_GETFILE_FAILED   3 
#define ZIP_CREATEFILE_FAILED  4 
#define ZIP_OPENPSDFILE_FAILED  5 
#define ZIP_OPENFILE_FAILED   6 
#define ZIP_READFILE_ERR   7 
#define MAX_BUFSIZE     102400 // 从zip文件中一次读取的最大缓冲值 

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                         )
{
    return TRUE;
}


// 在磁盘中创建路径strPath 
void CreateFilePath(CString strPath) 
{ 
int nPos; 
CString strFolder(""); 
for (nPos = 0; nPos != -1; nPos = strPath.Find("\\")) 
{ 
  nPos = strPath.Find("\\"); 
  strFolder += strPath.Left(nPos); 
  if (PathFileExists(strFolder)!=1) 
  { 
   CreateDirectory(strFolder, NULL); 
  } 
  strPath = strPath.Mid(nPos+1); 
  strFolder += "\\"; 
} 
}


// 格式化路径,把'/'改成'\\'
void FormatDirectorys( LPSTR lpszDirectorys )
{
if( lpszDirectorys!= NULL )
{
  int i=0;
  while( lpszDirectorys[ i ] !=  _T('\0') )
  {
   if( lpszDirectorys[ i ] == _T('/') )
   { 
    lpszDirectorys[ i ] = _T('\\');
   }
   i++;
  }
}
}


 
//函数名称:UnzipFile 
//函数功能:解压zip文件 
//输入参数:strFilePath 带解压zip文件的路径+名称 
//     strTmpPath  解压到这个路径下 
//     strPsd    密码 
//返 回 值:参考ConfigInfo.h 
int __stdcall UnzipFile(char* FilePath, char* TmpPath, char* Psd) 
{ 
//char*转换为CString
CString strFilePath;
strFilePath.Format("%s",FilePath);
  CString strTmpPath;
strTmpPath.Format("%s",TmpPath);
  CString strPsd;
strPsd.Format("%s",Psd);

unzFile uf = NULL; 
unz_global_info *p_gInfo = NULL; 
unz_file_info   *p_fInfo = NULL; 
p_gInfo = new unz_global_info; 
p_fInfo = new unz_file_info; 
CString strZipPath = strFilePath; 
long vfilesize;
long vlastsize;
  
  
uf = unzOpen(strZipPath);     // 打开zip文件,返回文件句柄 
if (NULL == uf) 
  return ZIP_OPEN_FAILED;     // 打开失败 
if (UNZ_OK != unzGetGlobalInfo(uf, p_gInfo))// 向*pglobal_info结构体中写入zip的信息 
  return ZIP_GETGLOBAL_FAILED;   // 获取zip信息失败 
CString strZipFName(_T(""));     // 用于存放szZipFName 
CString strFolderName(_T("")); 
CString strDiskPath(_T(""));     // 创建磁盘路径(文件夹)时会用到 
CString strDiskFile(_T(""));     // 创建磁盘文件时会用到 
char szZipFName[MAX_PATH] = "0";   // 存放从zip中解析出来的“文件(信息块)”名字 
char szReadBuf[MAX_BUFSIZE] = "0"; 
int  nNum = 0;       // unzReadCurrentFile读取的字符数 
DWORD dWrite = 0;       // 实际写入的字节数 
int nState = strFilePath.ReverseFind(_T('\\')); 
//strTmpPath += CString(_T("\")) + strFilePath.Mid(nState+1, strFilePath.ReverseFind(_T('.'))-nState-1); 
CreateFilePath(strTmpPath);     // strFilePath为F:\\file.zip,解压到E:\\TEST下,则先创建目录E:\\TEST\\file 
for (int i = 0; i < p_gInfo->number_entry; i++) 
{ 
  // for reading the content of the current zipfile, you can open it, read data 
     // from it, and close it (you can close it before reading all the file) 
  if (UNZ_OK != unzGetCurrentFileInfo(uf, p_fInfo, szZipFName, MAX_PATH, NULL, 0, NULL, 0)) 
   return ZIP_GETFILE_FAILED; 
  switch (p_fInfo->external_fa) 
  { 
  case FILE_ATTRIBUTE_DIRECTORY:  // 文件夹 
   { 
    FormatDirectorys(szZipFName); 
    strFolderName = szZipFName; 
    strDiskPath = strTmpPath + CString(_T("\\")) + strFolderName; 
     
    CreateFilePath(strDiskPath); // 创建目录(文件夹) 
    break; 
   } 
    
  default:       // 文件 
   { 
    FormatDirectorys(szZipFName); 
     vfilesize=p_fInfo->uncompressed_size;
    strZipFName = szZipFName; 
    strDiskFile = strTmpPath + CString(_T("\\")) + strZipFName; 
    HANDLE hFile = CreateFile(strDiskFile, GENERIC_WRITE, // 对文件进行只写访问 
          0,        // 独占对文件的访问 
          NULL, OPEN_ALWAYS,    // 打开已有文件,若存在则直接打开,否则创建新文件 
          FILE_FLAG_WRITE_THROUGH, // 隐藏文件 | 进制对文件写入操作进行缓存以减少数据丢失的可能性 
          NULL); 
    if (INVALID_HANDLE_VALUE == hFile) 
     return ZIP_CREATEFILE_FAILED;      // 文件打开(创建)失败 
    if (strPsd.IsEmpty()) 
    { 
     if (UNZ_OK != unzOpenCurrentFile(uf)) 
     { 
      CloseHandle(hFile);   // 打开失败 
      return ZIP_OPENFILE_FAILED; 
     } 
    } 
    else 
    { 
     if (UNZ_OK != unzOpenCurrentFilePassword(uf, strPsd)) 
     { 
      CloseHandle(hFile);   // 打开有密码的zip压缩包中的文件失败 
      return ZIP_OPENPSDFILE_FAILED; 
     } 
    } 
   
     long count=0;
     vlastsize = vfilesize;
     while(TRUE) 
    { 
     nNum = 0; 
     count++;
     memset(szReadBuf, 0, MAX_BUFSIZE);

     if(vlastsize>=MAX_BUFSIZE)
     {
          nNum = unzReadCurrentFile(uf, szReadBuf, MAX_BUFSIZE); // 从zip中读数据 
     }else{
          nNum = unzReadCurrentFile(uf, szReadBuf, vlastsize); // 从zip中读数据 
     }

   
     if (nNum < 0) 
     { 
      unzCloseCurrentFile(uf); 
      CloseHandle(hFile); 
      return ZIP_READFILE_ERR; 
     } 
     else if (nNum == 0) 
     { 
      unzCloseCurrentFile(uf); 
      CloseHandle(hFile); 
      break; 
     } 
     else 
     { 

          if(vlastsize>=MAX_BUFSIZE)
          {
               if (!WriteFile(hFile, szReadBuf, MAX_BUFSIZE, &dWrite, NULL))// 往本地磁盘写数据 
                 { 
                  unzCloseCurrentFile(uf); 
                  CloseHandle(hFile); 
                  return (GetLastError()); 
                 } 
          }else{
               if (!WriteFile(hFile, szReadBuf, vlastsize, &dWrite, NULL))// 往本地磁盘写数据 
                 { 
                  unzCloseCurrentFile(uf); 
                  CloseHandle(hFile); 
                  return (GetLastError()); 
                 } 
          }

          } 


    
     if(vlastsize>=MAX_BUFSIZE)
     {
          vlastsize = vlastsize - MAX_BUFSIZE;
     }else{
          vlastsize = vlastsize;
     }
    
    }
    
    break; 
   } 
    
  } 
  unzGoToNextFile(uf); 
} 
if (uf) 
  unzClose(uf); 
return -1; 
} 
<div><div style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; FONT: medium Tahoma; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"> </div></div>

     5. 这时候编译会报一些错误。
     6. 将zlib文件夹放到工程目录下。不放会报一下错误:Cannot open include file: 'zlib\unzip.h': No such file or directory。
     7. 这时编译会报一下错误:
LIBCMTD.lib(crt0init.obj) : warning LNK4098: defaultlib "msvcrt.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
解决办法:
project -- settings-- 连接 --工程选项下 增加 /NODEFAULTLIB:msvcrt.lib 字符串。
     8. project -- settings-- c/c++ --code generation -- use runtime library --debug multithreaded dll
预处理器  下 预处理器定义 去掉_USERDLL  增加 _AFXDLL  
在c/c++下的工程选项里 去掉 /GZ 或者 /GD
     9.创建def文件
新建--文件--文本文件   增加代码:
LIBRARY      "unzip"

EXPORTS
    UnzipFile   @1

进入工程目录下,修改扩展名txt改为def

在vc++6.0面板上的unzip files 右键 -- 添加文件到工程-- 选择def类型的文件--选择unzip 确定。

     10. build构建动态链接库。就可以用了。
     11.PB8调用unzip.dll
引用:
function long UnzipFile(string FilePath,string TmpPath,string Psd) library 'unzip.dll'

代码:
string ls_src,ls_dst

ls_src='F:\\131\\15\\150010\\1\\131.zip'
ls_dst='F:\\131\\15\\150010\\1\\3\\'


string ls_psd
ls_psd = 'mima'

long ret

ret = UnzipFile(ls_src,ls_dst,ls_psd)

messagebox('','解压完毕!'+string(ret))
 

(二)、c#编写的解压带有密码的压缩文件
以下是dll项目Unzip.cs里的内容,项目要引用 ICSharpCode.SharpZipLib.dll文件
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace unzipfile
{
    [Guid("a1462ebc-1f88-4d2a-b677-48f61b834907")]
    public class Unzip
    {
        /// <summary>
        /// 实现解压操作
        /// </summary>
        /// <param name="zipfilename"> 要解压文件Zip(物理路径) </param>
        /// <param name="UnZipDir"> 解压目的路径(物理路径) </param>
        /// <param name="password"> 解压密码</param>
        /// <returns> 异常信息</returns>

        public string UnMakeZipFile(string zipfilename, string UnZipDir, string password)
        {
            //判断待解压文件路径
            if (!File .Exists(zipfilename))
            {
                File.Delete(UnZipDir);
                return "待解压文件路径不存在!" ;
            }

            //创建ZipInputStream
            ZipInputStream newinStream = new ZipInputStream( File.OpenRead(zipfilename));

            //判断Password
            if (password != null && password.Length > 0)
            {
                newinStream.Password = password;
            }

            //执行解压操作
            try
            {
                ZipEntry theEntry;

                //获取Zip中单个File
                while ((theEntry = newinStream.GetNextEntry()) != null)
                {
                    //判断目的路径
                    if (!Directory .Exists(UnZipDir))
                    {
                        Directory.CreateDirectory(UnZipDir);//创建目的目录
                    }

                    //获得目的目录信息
                    string Driectoryname = Path .GetDirectoryName(UnZipDir);
                    string pathname = Path .GetDirectoryName(theEntry.Name);//获得子级目录
                    string filename = Path .GetFileName(theEntry.Name);//获得子集文件名

                    //处理文件盘符问题
                    pathname = pathname.Replace( ":", "$" );//处理当前压缩出现盘符问题
                    Driectoryname = Driectoryname + "\\" + pathname;

                    //创建
                    Directory.CreateDirectory(Driectoryname);

                    //解压指定子目录
                    if (filename != string .Empty)
                    {
                        FileStream newstream = File .Create(Driectoryname + "\\" + filename);

                        int size = 2048;

                        byte[] newbyte = new byte[size];

                        while (true )
                        {
                            size = newinStream.Read(newbyte, 0, newbyte.Length);

                            if (size > 0)
                            {
                                //写入数据
                                newstream.Write(newbyte, 0, size);
                            }
                            else
                            {
                                break;
                            }

                        }
                        newstream.Close();
                    }

                }
                newinStream.Close();
            }
            catch (Exception se)
            {

                return se.Message.ToString();
            }
            finally
            {
                newinStream.Close();
            }


            return "" ;
        }
    }

}

2.需要使用vs2012开发人员命令提示工具找到dll所在目录 执行 regasm unzipfile.dll /tlb:unzipfile.tlb

3. PB程序调用:

增加一个实例变量

OLEObject unzip

在窗体的Open()事件里面写下以下代码

unzip= Create OLEObject
unzip.ConnectToNewObject("unzipfile.Unzip")

"unzipfile" 是你C#写的DLL的命名空间的名称

"Unzip"是你的DLL的类名称.别搞错了.

PB程序调用:

string ls_src,ls_dst

ls_src='F:\\13215001010029.zip'
ls_dst='F:\\13215001010029\\'


string ls_psd
ls_psd = 'aaaa'

string ls_ret

ls_ret = unzipf(ls_src,ls_dst,ls_psd)

messagebox('','解压完毕!'+ls_ret)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值