Classic Object Pascal for free
I'm having trouble with FileExists & SysFindFirst etc - where it can't find a file that I can see perfectly well in Windows Explorer.
When I capture the name & examine it in hex, it contains x'BA' .. probably because the filename was done on a non-US keyboard .. or similar. There are quite a few like this & I need to access them via a program/utility I'm writing.
NB: I have also examined the names carefully in the debugger, and yes, they are correct on entering either of the 2 routines. But both routines fail when using the relevant longname - which I am 100% certain is correct! As I say, Windows Explorer finds them ok.
I suspect that the 2 routines will work fine *if* I access the filenames via the DOS-style (8.3) names,
instead of the Windows long filenames. ie: I'm pretty sure that's where the problem lies.
But ... I can't seem to find anything which returns the 8.3 filename (eg: ROBERT~3.TXT style)
Yes I've looked and looked ... But .. I'm getting old now - so maybe I missed it! :-)
I can 'kludge' finding the short name .... by doing a "DIR /X" and saving the list to a file & then reading
that ... but ...... what a kludge! ie: a pretty nasty workaround Hardly .. umm.. elegant :-)
Does anyone have a better/proper way to get to the 8.3 filename pls?
NB: If possible, I don't want to have to open/close the file - there are thousands to check!
......Unless that's the *only* way.
NB: The files are on a UNC path .. tho' that should not really make any difference!
(It's not a network or permissions issue - pls don't let's get sidetracked :-)
You might want to have a look at
Don't ask me how to call API functions from VP...
Probably the files contain unicode, afaik legacy 8.3 is not generated for them.
You will need to create your own file functions based on "-W" versions of the relevant API functions of all related path routines, which take UTF16 pwchar arguments, together with a 16-bit version of tsearchrec
The "W" functions are the native Windows NT+ functions, the -A are win32 (win9x+winnt combined subset) and only understand ascii.
Probably you can nick the relevant declarations, and even functions from Lazarus and/or Free Pascal development versions, which are gearing up to replace the standard functions by -W functions by default.
A workaround for that could be to mostly work in utf8, and only convert to two byte before calling an api function
Worse, the commandline shell (cmd.exe) can't seem to handle these either. I'm already considering migrating ot powershell long term.
Note that recent server versions of Windows disable 8.3 generation all together. (though afaik you can turn them back on by registry)
More importantly, maybe my above post was wrong, maybe you only need to call the -W version of the getshortpathname function to get a 8.3 for those files.
Thanks for all the replies ... ( I see we managed to get sidetracked after all :-) ie: ... Unicode ) :-))
BTW .. sorry for the delay .. (I'm on dialup)...
It seems that I have to use Windows API from what you all say .. which is another problem as I have no knowledge of
"Windows" programming .. (...I have been programming "screens" for years with ABAP (SAP) until I retired...& SAP makes it all very very simple .. ie: little or no knowledge of the underlying OS is needed)!
So .. does anyone have an example of calling the Windows API from VP which I can use as a basis please?
As to the "Unicode issue" ...
I have a simple way of solving a "Unicode" file - which seems to work for all that I have encountered so far ...Tho' I doubt if it will work for everything.
It seems that in such a file, all the characters are preceded by an Ascii Null (#0) - so I read the file into a buffer & I have an assembler routine which just copies all the characters to another buffer whilst ignoring the Nulls...
At which point that buffer can be either used - or written back to the original file. .Simple !
(....But probably won't work for everything ..... surprise)!
However, for the moment that is not the problem I'm encountering.
I just need to be able to rename the files - not process them in any way - and I have found that the VP RenameFile (SysUtils) works fine on Long filenames & across the network on UNC names as well.
But .. I first need to detect (with FileExist) that the file does still exist .. and that is where the need to (have to) use
8.3 names seems to be necessary - as it just doesn't seem to work with the filenames containing special characters that I mentioned initially <sigh>.
I suppose I could just issue the rename and just check whether it worked ... Tho' it goes against all I have been taught over the years to program that way ! :-)) But then .. if it didn't work under FileExists .. why should I expect it to find that file & work under RenameFile anyway?.. <....sigh> :-))
Anyway . thanks again to all ... Any other ideas or comments?
Afaik Windows generates unicode (utf16, two byte unicode) filenames only when it can't be represented in the current codepage. So that should mean that some of the "zeros" are not zeroes in this case, and you can't simply leave them out.
Sometimes however the files are unicode because of the name was copied and pasted from a texteditor which uses a different (typographic) form of apostrophe.If the filename looks normal but contains typographical characters like apostrophe, replace them in explorer. That might clear the unicode status.
As for doing it in an automated manner, search for a tutorial on the net. The needed api functions can be easiest gleaned from the VP runtime library. Look what api function they (findfirst/next/fileexists) ultimately call, replace the A with W (or add a W), and look it up on the internet.
Most functions taking a string (pchar) will exist in A and W versions.
Well as I said .. probably doesn't work for everything .. but .. has worked for all the ones I've tried so far ...
As to the tutorials part ...
I have, of course, looked at the VP code, scanned the net etc .. but find it all too daunting to have to learn all about Windows programming just to solve a (relatively) simple issue..
Seeing as it would seem to be something that would have been needed long before now, I had hoped that something would be around .... but I have been known to 'live in hope' .. a tad fruitlessly! :-))
I still live in hope that something will turn up.... :-))
If you want to have it easy, Delphi versions 2009 and up are the only choice. But they are pricey.
As said FPC is working on it, and the next major release will use -W functions by default. That is still some time away though.
Somebody VP could get some of the FPC sources and try to make an helper unit, but considering the activity on this forum (this thread being close to an year's flow), that is unlikely.