最近用 IShellDispatch 来解压/压缩 Zip包。使用过程中遇到这个问题,CopyHere函数是异步的开启一个线程来执行解压/压缩的,这样我就很难控制 CopyHere函数开启的这个线程 什么时候结束。小弟对COM不熟悉,查了几天资料没找到好的解决方案,特在此发帖,希望得到各位帮助。
需要实现:等待压缩/解压完成后,才能继续往下执行。 (注:不想使用第三方的库来实现解压/压缩)
CopyHere 启动线程时,我该如何知道线程结束呢?困扰几天了,希望能够得到你的帮助.思路是:由于CopyHere是开启一个异步的线程来压缩Zip文件的.所有在压缩之前想先获得 FolderItems 的总数initialCount ,然后CopyHere会执行,在循环里获取FolderItems 的个数lCount,比较 initialCount 和 lCount;如果添加FolderItems 完成(即压缩完成),才继续运行.最终调试结果, initialCount 和 lCount 恒等. 悲剧ING.
我的代码如下:////////////////////////////////////////////---测试---//////long lCount = 0;long instanceCount = 0;long initialCount = 0;
//CHN 获得文件数目FolderItems* pFolderItems = NULL;hResult = pFromFolder->Items(&pFolderItems);if (S_OK != hResult){return FALSE;}hResult = pFolderItems->get_Count(&lCount);if (S_OK != hResult){return FALSE;}initialCount = lCount;
//CHN 初期化VariantInit(&vOpt);vOpt.vt = VT_I4;vOpt.lVal = FOF_NO_UI; 
//CHN 拷贝文件并添加到Zip包中hResult = pToFolder->CopyHere(vFile, vOpt);if(S_OK != hResult){return FALSE;}Sleep(1000);
while (instanceCount <= initialCount){Sleep(100);
long lCount = 0;hResult = pFolderItems->get_Count(&lCount);if (S_OK != hResult){return FALSE;}instanceCount = lCount;}

解决方案 »

  1.   

    看看这里http://hi.baidu.com/xuzhenquan/blog/item/063de4fe131e562e5d600847.html
    看了下,你没在 hResult = pToFolder->CopyHere(vtDispatch,vOpt)后面调用hResult = pToFolder->Items(&pToFolderItems)导致pToFolderItems指向的是pFromFolder里的item数量
      

  2.   


    谢谢 fishion 的回答。
    现在的情况是 获取zip包中的文件个数时,总是为0(即使成功压缩zip包后,zip包有几百兆,获取的文件个数还是0,是不是不是我这样获取的zip包个数的?),盼回答。附代码:
    long lFolderNum = 0;
    long lZipFileNum = 0;
    FolderItems* pFromFolderItems = NULL;
    hResult = pFromFolder->Items(&pFromFolderItems);
    hResult = pFromFolderItems->get_Count(&lFolderNum);//第一级目录文件夹个数
    //初期化
    VariantInit(&vOpt);
    vOpt.vt = VT_I4; vOpt.lVal = FOF_NO_UI;  
    //CHN 拷贝文件并添加到Zip包中
    hResult = pToFolder->CopyHere(vFile, vOpt);
    if(S_OK != hResult)
    {
    return FALSE;
    } Sleep(1000); FolderItems* pToFolderItems = NULL;
    hResult = pToFolder->Items(&pToFolderItems);
    hResult = pToFolderItems->get_Count(&lZipFileNum); while(lZipFileNum < lFolderNum)
    {
    //这里获取的个数总是为0,会造成死循环 hResult = pToFolderItems->get_Count(&lZipFileNum);
    }
      

  3.   

    解压zip就是一个函数,没有必要用com
      

  4.   

    zlib压缩 解压都是一个函数(1)int compress (Bytef *dest,   uLongf *destLen, const Bytef *source, uLong sourceLen);
    把源缓冲压缩成目的缓冲, 就那么简单, 一个函数搞定
    (2) int compress2 (Bytef *dest,   uLongf *destLen,const Bytef *source, uLong sourceLen,int level);
    功能和上一个函数一样,都一个参数可以指定压缩质量和压缩数度之间的关系(0-9)不敢肯定这个参数的话不用太在意它,明白一个道理就好了: 要想得到高的压缩比就要多花时间
    (3) uLong compressBound (uLong sourceLen);
    计算需要的缓冲区长度. 假设你在压缩之前就想知道你的产度为 sourcelen 的数据压缩后有多大, 可调用这个函数计算一下,这个函数并不能得到精确的结果,但是它可以保证实际输出长度肯定小于它计算出来的长度
    (4) int uncompress (Bytef *dest,   uLongf *destLen,const Bytef *source, uLong sourceLen);
    解压缩(看名字就知道了:)
      

  5.   

    GetExitCodeThread
    The GetExitCodeThread function retrieves the termination status of the specified thread. BOOL GetExitCodeThread(
      HANDLE hThread,      // handle to the thread
      LPDWORD lpExitCode   // address to receive termination status
    );
     
    Parameters
    hThread 
    Handle to the thread. 
    Windows NT: The handle must have THREAD_QUERY_INFORMATION access. lpExitCode 
    Pointer to a 32-bit variable to receive the thread termination status. 
    Return Values
    If the function succeeds, the return value is nonzero.If the function fails, the return value is zero. To get extended error information, call GetLastError. Res
    If the specified thread has not terminated, the termination status returned is STILL_ACTIVE. If the thread has terminated, the termination status returned may be one of the following: 
      

  6.   

    while里加个sleep(1000);之类的
    还有就是,你得把有出现 hResult 的地方都进行判断下,看看是否成功了
      

  7.   


    谢谢schlafenhamster的回复
    可是我根本没法获得线程的handle
      

  8.   


    while里面加了sleep(1000)了,Zip都压缩完成了,还是不能退出while循环
      

  9.   

    您好, 我现在也遇到了相似的问题,请问楼主,找到解决方法了么?是用 文件count(包容器中对象的个数),还是其他的方法来解决的?