Re: SHFileOperation Error when Copying Directory( Source Code Attached
"Landon" <Landon@discussions.microsoft.com> ha scritto nel messaggio
news:65D87648-7941-45B2-B644-088EC1BE8E4A@microsoft.com...
I use MFC Visual C++ 4.2.
I use SHFileOperation to copy a directory contents.
I found that the files on the Destination folder is not the same as the
Source. This is dangerous.
Here is my function:
void CToiawaseDlg::CopyDirectory( CString Src, CString Dest )
I would pass CString input parameters by const reference:
CopyDirectory( const CString & Src, const CString & Dest )
{
SHFILEOPSTRUCT file;
char* pSrc = new char[Src.GetLength() + 2];
memset( pSrc, NULL, Src.GetLength() + 2 );
memcpy( pSrc, Src.GetBuffer( Src.GetLength() ), Src.GetLength() );
This code is not Unicode-aware.
I would refactor it to make it Unicode aware:
// Allocate memory
TCHAR * pSrc = new TCHAR[ Src.GetLength() + 2 ];
// Copy string (scale byte count by sizeof TCHAR)
memcpy( pSrc, Src.GetString(), (Src.GetLength() + 1) * sizeof(TCHAR) );
// Make string double-NUL terminated
pSrc[ Src.GetLength() + 1 ] = _T('\0');
Moreover, I would build a simple function to wrap the double-NUL terminating
thing, and I would use std::vector< TCHAR > instead of new[] and delete[],
for several reasons, e.g. std::vector is exception-safe, and does not
require explicit delete[] (it uses RAII).
You may want to try the following CopyDirectory() code I wrote, which seems
to run fine on a simple test I've done:
<code>
#include <ShellAPI.h>
#include <vector>
typedef std::vector< TCHAR > TCharArray;
//------------------------------------------------------------------------
// Given an input string 'str', makes a buffer 'dest' storing the input
// string with a double NUL termination \0\0.
//------------------------------------------------------------------------
void DoubleNullTerminateString( OUT TCharArray & dest, const CString & str )
{
int len = str.GetLength();
// Make room for double NUL termination
dest.resize( len + 2 );
// Copy source string in destination buffer
memcpy( &dest[0], str.GetString(), len * sizeof(TCHAR) );
// Add double NUL termination \0 \0
dest[ len ] = TEXT('\0');
dest[ len + 1 ] = TEXT('\0');
}
//------------------------------------------------------------------------
// Copies the content of source directory to destination directory.
// Returns TRUE on success.
//------------------------------------------------------------------------
BOOL CopyDirectory( const CString & src, const CString & dest )
{
//
// Double NUL terminate strings for SHFileOperation
//
TCharArray sourceBuf;
DoubleNullTerminateString( sourceBuf, src );
TCharArray destBuf;
DoubleNullTerminateString( destBuf, dest );
//
// Prepare copy operation structure
//
SHFILEOPSTRUCT file;
file.hwnd = ::GetActiveWindow();
file.wFunc = FO_COPY;
file.pFrom = &sourceBuf[0];
file.pTo = &destBuf[0];
file.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT;
file.hNameMappings = NULL;
//
// Do the copy
//
if ( ::SHFileOperation( &file ) )
{
// Error
return FALSE;
}
// All right
return TRUE;
}
</code>
Giovanni