Copy, Move, Rename File Preserving Destination Name Case

The CopyFile() and MoveFile() WIN API functions preserve the case of the name for the destination file. Alternatively, WSH can be used.
The source and destination file names should include the directory name in both cases.

Note 1 A Copy operation will not change file name case when destination file already exists (overwritten).

Note 2 The WinApiErrMsg is used to retrieve Windows API error message in case of error.

This is sample code. Add error handling and adjust to your requirements as necessary.

lcFileName = <...>
lcCopyFileName = <...>
 
IF CopyFile(lcFileName, lcCopyFileName, 0) = 0
  ? "Copy unsuccessful:" + WinApiErrMsg(GetLastError() ) 
ENDIF
 
lcFileName2 = <...>
lcNewFileName =  <...>
 
* Move/Rename file
IF MoveFile(lcFileName2, lcNewFileName) = 0
  ? "Move/Rename unsuccessful"
ENDIF
 
RETURN
 
FUNCTION CopyFile(tcFileName, tcCopyFileName, tnFailIfExists)
DECLARE Long CopyFile IN WIN32API String SourceFileName, String DestFileName, Long bFailIfExists
RETURN CopyFile(tcFileName, tcCopyFileName, tnFailIfExists)
 
FUNCTION MoveFile(tcFileName, tcNewFileName) 
DECLARE Long MoveFile IN WIN32API String SourceFileName, String DestFileName
RETURN MoveFile(tcFileName, tcNewFileName)
* WSH
* Copy file
* The file name case will not be changed for existing destination file.
oFSO = CreateObject("Scripting.FileSystemObject")
llOverWrite = .T.
TRY 
	oFSO.CopyFile(lcFileName, lcCopyFileName, llOverWrite)
CATCH 
	? "Copy unsuccessful"
ENDTRY
* Move/Rename file
oFSO = CreateObject("Scripting.FileSystemObject")
TRY 
	oFSO.MoveFile(lcFileName, lcNewFileName )
CATCH 
	? "Move/Rename unsuccessful"
ENDTRY
Your rating: None Average: 5 (4 votes)

Interesting finding with CopyFile

Sergey, using the WinAPI CopyFile, it seems that if the destination file already exists and is overwritten by CopyFile, the resulting file name will be in the same case as the file that was overwritten, and will not preserve the case of the source file. Strange, huh?

Existing destination files

Hi Matt,

I guess you didn't read the code or you would see following comment there: "the file name case will not be changed for the existing destination file". It's applicable and commented for WSH as well.

Declaring multiple times?

Hi Sergey,

There does not seem to be any way to test if the function has already been delcared already and is ready to go (on subsequent firing of the same code). Is there a way to test (other than parsing that which is returned from DISPLAY STATUS). Or if not, does it really matter if the same DECLARE statement is fired multiple times?

Re: Declaring multiple times?

Hi Albert,

Declaring a DLL multiple times does not bear a big penalty but you can avoid it altogether by using a trick I learn from GdiPlusX project. Check updated code above.

Declared DLL function name precedence

Does it mean that Declared DLL function name takes precedence over UDF name?
TIA

Re: Declared DLL function name precedence

Hi Andrzej,

Yes, external functions from DLL or FLL take precedence over UDF with the same name.

Rename Preserving Case

Just wanted to thank you, Sergey, for your excellent solution to "Copy, Move, Rename File Preserving Destination Name Case". I was attempting to automate the renaming of CamelCase Excel files when I noticed that RENAME was not going to work for me. Your solution worked perfectly.
I was then about to search your site for an ADIR() equivalent because it returns UPPERCASE until I saw in the help that VFP9 has a flag to preserve case.
Thanks again!
Ed

Work great!

It work great!
I think that a lot of code can be better (for example evaluate if the destiny file exist, then use movefile, else, copyfile) but the hard work it's done!
Thank you!