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. $SAMPLECODE$

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

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)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

* 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

Comments

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?

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.

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?

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.

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

Hi Andrzej,

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

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

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!