如何将IFileOperation CopyItem用于目标ZIP文件

时间:2015-04-26 18:04:51

标签: c++ windows shell visual-c++ desktop

我正在使用IFileOperation接口的CopyItems方法将另一个文件从源文件夹复制到目标文件夹。只要目标文件夹是标准文件系统目录,这就可以正常工作。但是,我使用IFileOperation而不是SHFileOperation()方法的主要动机是允许从/向非文件系统对象复制项目,如文档所述(https://msdn.microsoft.com/en-us/library/windows/desktop/bb775771%28v=vs.85%29.aspx)。

以下代码适用于文件系统目标,例如“g:\ my folder”但如果目的地是ZIP文件,则不起作用,例如“g:\ Super Cars.zip”。对于这个快速示例,请忽略资源泄漏:)。

请注意,ZIP文件是使用Windows的标准内置ZIP功能创建的现有ZIP文件,它不包含我正在尝试复制的文件。


        #include "stdafx.h"
        #include <Windows.h>
        #include <shellapi.h>
        #include <Shlobj.h>
        #include <iostream>
        #include <atlbase.h>

        void CopyFile(LPCTSTR strSource, LPCTSTR strDestination)
        {
        PIDLIST_ABSOLUTE abSourcePidl = nullptr;
        SFGAOF attrs;

        HRESULT hr = SHParseDisplayName(strSource, nullptr, &abSourcePidl, 0, &attrs);    
        if (FAILED(hr))
        {
            std::wcout << _T("SHParseDisplayName failed for ") << strSource << std::endl;
            return;
        }

        PIDLIST_ABSOLUTE abDestPidl = nullptr;

        hr = SHParseDisplayName(strDestination, nullptr, &abDestPidl, 0, &attrs);
        if (FAILED(hr))
        {
            std::wcout << _T("SHParseDisplayName failed for ") << strDestination << std::endl;
            return;
        }

        IShellItem2* pDestShellItem;

        hr = SHCreateItemFromIDList(abDestPidl, IID_IShellItem2, reinterpret_cast<LPVOID*>(&pDestShellItem));
        if (FAILED(hr))
        {
            std::wcout << _T("SHCreateItemFromIDList failed") << std::endl;
            return;
        }

        PIDLIST_ABSOLUTE* pPidlRawArray = new PIDLIST_ABSOLUTE[1];
        pPidlRawArray[0] = abSourcePidl;

        IShellItemArray* pShellItemArr = nullptr;
        hr = SHCreateShellItemArrayFromIDLists(1, (LPCITEMIDLIST*)pPidlRawArray, &pShellItemArr);
        if (FAILED(hr))
        {
            std::wcout << _T("SHCreateShellItemArrayFromIDLists failed") << std::endl;
            return;
        }

        CComPtr<IFileOperation> fileOp;
        hr = fileOp.CoCreateInstance(CLSID_FileOperation);
        if (FAILED(hr))
        {
            std::wcout << _T("Creation of IFileOperation failed") << std::endl;
            return;
        }

        hr = fileOp->CopyItems(pShellItemArr, pDestShellItem);
        if (FAILED(hr))
        {
            std::wcout << _T("CopyItems fall failed") << std::endl;
            return;
        }

        hr = fileOp->PerformOperations();
        if (FAILED(hr))
        {
            std::wcout << _T("PerformOperations call failed") << std::endl;
            return;
        }

        std::wcout << _T("File copied successfully") << std::endl;
    }


    int _tmain(int argc, _TCHAR* argv[])
    {
        CoInitialize(NULL);

        CopyFile(_T("D:\\TEMP\\COMTIME.TXT"), _T("G:\\My Folder")); // WORKS!!
        CopyFile(_T("D:\\TEMP\\COMTIME.TXT"), _T("G:\\Super Cars.zip")); // DOES NOT WORK!!

        CoUninitialize();

        return 0;
    }

0 个答案:

没有答案