Re: need native call help
On 4/18/24 04:50, yary wrote: I did a lot of very deep windows programming in my previous job and reminding me that I would always use the 8.3 short name for file operations! dir /x will get it for you. Must be API called for it also. Probably only works on local volumes not network rounded ones. Just a guess. AreShortNamesEnabled function (fileapi.h) https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-areshortnamesenabled and GetShortPathNameW function (fileapi.h) https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getshortpathnamew The silly "W" at the above means you have to convert your string to UTF16. If yo have a "A" at the end, you can just use UTF8. I have modules for to convert both the them. I've run into problems on some unix shells with maximum command-line lengths. -y Hi Yary, The 64 thousand dollar questions is should the programming language make allowances for the "quirks" of an operating system, such as the 260 file limit DeleteFileA, and just presume the user of the programming language has no business programming for the particular operating system if he does not already know the quirks or should the programming language make allowances? As for me, when I throw unlink at a file, I expect it to work or at least be told why not. So, I think allowances show be made. In my DeleteFileA module, I obviously wanted it to just work, quirks or no quirks, so I could just go about deleting what I want without having to be a genius at the operating system and wasting hours troubleshooting things that don't work as expected. In an "ideal world", I never have to goof around with API calls, unless I was shooting for something really weird. Your take? -T
Re: need native call help
I did a lot of very deep windows programming in my previous job and reminding me that I would always use the 8.3 short name for file operations! dir /x will get it for you. Must be API called for it also. Probably only works on local volumes not network rounded ones. Just a guess. I've run into problems on some unix shells with maximum command-line lengths. -y On Wed, 17 Apr 2024 at 11:58 PM, ToddAndMargo via perl6-users < perl6-us...@perl.org> wrote: > On 4/17/24 19:10, William Michels via perl6-users wrote: > > Hi Todd, > > > > Here are a few U StackExchange answers that I wrote using Raku's > `unlink`: > > > > > https://unix.stackexchange.com/questions/459521/how-to-truncate-file-to-maximum-number-of-characters-not-bytes/751267#751267 > > > > > https://unix.stackexchange.com/questions/749558/remove-exact-line-from-file-if-present-leave-the-rest-of-lines-error-handling/749581#749581 > > > > (Suggestions welcome). > > > Hi William, > > unlink($_) if $bak.IO:e & $bak.IO:f; > > Interesting! Thank you. > > The problem is that you can not implicitly trust > the file operations when programming on the kluge. > Linux, no problem. > > I wish I had more Linux customers, but I do not. > > -T > > I do not know if you are, but I just append .tmp or .bak on to the name > of my program. I have never used Kernel32::GetTempTileNameA. > > > https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea >
Re: need native call help
On 4/17/24 19:10, William Michels via perl6-users wrote: Hi Todd, Here are a few U StackExchange answers that I wrote using Raku's `unlink`: https://unix.stackexchange.com/questions/459521/how-to-truncate-file-to-maximum-number-of-characters-not-bytes/751267#751267 https://unix.stackexchange.com/questions/749558/remove-exact-line-from-file-if-present-leave-the-rest-of-lines-error-handling/749581#749581 (Suggestions welcome). Hi William, unlink($_) if $bak.IO:e & $bak.IO:f; Interesting! Thank you. The problem is that you can not implicitly trust the file operations when programming on the kluge. Linux, no problem. I wish I had more Linux customers, but I do not. -T I do not know if you are, but I just append .tmp or .bak on to the name of my program. I have never used Kernel32::GetTempTileNameA. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea
Re: need native call help
Hi Todd, Here are a few U StackExchange answers that I wrote using Raku's `unlink`: https://unix.stackexchange.com/questions/459521/how-to-truncate-file-to-maximum-number-of-characters-not-bytes/751267#751267 https://unix.stackexchange.com/questions/749558/remove-exact-line-from-file-if-present-leave-the-rest-of-lines-error-handling/749581#749581 (Suggestions welcome). HTH, Bill > On Apr 17, 2024, at 17:14, ToddAndMargo via perl6-users > wrote: > > On 4/17/24 05:52, yary wrote: >> From unlink's documentation: >> If the file to be deleted does not exist, the routine treats it as success. >> So trying to delete a file that isn't there, doesn't have an error, which is >> kind of neat, but that is a difference from native delete. >> -y > > Hi Yary, > > Not to beat a dead horse, but when does that stop me! > > > In Windows, if the filename/path exceeds 260 characters > (MAX_PATH), unlink will think that the file does not > exist and will let you blissfully think it has been removed, > when in reality, it is still there. > > -T
Re: need native call help
On 4/17/24 05:52, yary wrote: From unlink's documentation: If the file to be deleted does not exist, the routine treats it as success. So trying to delete a file that isn't there, doesn't have an error, which is kind of neat, but that is a difference from native delete. -y Hi Yary, Not to beat a dead horse, but when does that stop me! In Windows, if the filename/path exceeds 260 characters (MAX_PATH), unlink will think that the file does not exist and will let you blissfully think it has been removed, when in reality, it is still there. -T
Re: need native call help
On 4/17/24 05:52, yary wrote: From unlink's documentation: If the file to be deleted does not exist, the routine treats it as success. So trying to delete a file that isn't there, doesn't have an error, which is kind of neat, but that is a difference from native delete. -y Hi Yary, Not neat at all. And that would be a bug that need to be fixed. I spend hours trying to troubleshoot why I could not delete a file. 1) it should return "File not Found" and 2) it should return "MAX_PATH exceed in file name" if that is the case and `\\?\` has not been prepended. And if such, recommend adding `\\?\`. Or just add it automatically as my ApiDeleteFile module does. This is Windows we are dealing with after all. Oh look how it is done in Linux when deleting a non-existent file: $ rm abc.txt ; echo $? rm: cannot remove 'abc.txt': No such file or directory 1 The "No such file or directory" is self explanatory. The "1" from the echo of "$?" means the command failed, unlike the no error return from Raku's unlink. Unlink need to be fixed. -T
Re: need native call help
On 4/17/24 05:50, yary wrote: What does the windows native delete do which you need, that raku's unlink doesn't have? without unlink $FileName { say "Could not delete $FileName:", .exception.message }; -y Hi Yary, This is Windows we are dealing with. It is a kluge. I have had unlink fail and could not figure out why. DeleteFileA has wonderful error reporting, well for Windows. And you can always count on it doing things right. Well, again, maybe.. What caused me to do all this was my inability to delete the following from the command shell, powershell, and (Raku) unlink. But I could delete from Windows Explorer. I kept getting told the command could not find the file. H! D:\MyDocsBackup\backup2\Mozilla 2024-03-26 16;10;20 (Full)\Firefox\Profiles\pj0elosu.default-release\storage\default\https+++505991220932649.webpush.freshchat.com^partitionKey=%%28https%%2Cbid13.com%%29\cache\morgue\114\{7cccd5e9-a7aa-4349-a2e9-569baf007272}.final I had originally thought that the issue was the "weird" characters. All my attempts to escape the failed. So out of desperation, I switched to DeleteFileA. On DeleteFileA's web page was the give away: 'Tip Starting with Windows 10, Version 1607, you can opt-in to remove the MAX_PATH limitation without prepending "\\?\"' And I did not realize this a first, but a thorough reading of the web page and I finally understood. The file I was trying to delete was 265 characters long and the limit (MAX_PATH) was 260. The commands I was trying were lopping off five of the characters. And the commands did not tell me I had exceeded MAX_PATH. (This is M$ we are dealing with after all.) Now you all that live sheltered lives with Linux, this would not be an issue. But the kluge, it is. You can have to different max lengths and you have to know when and when not to prepend. I am sorry, but what poor programming on M$'s part. (Prepending works on shorter files, but takes longer to process and sometimes coughs.) You will notice my modules a few things: 1) if the length of the path/name exceeds MAX_PATH and the path/name does not include \\?\`, then I prepend it. 2) if DeleteFileA return pass, I send back "OK" in the string. If not, I send back the error message from Kernel32::GetLastError" (returns a number) and Kernel32::WinFormatMessage (translates the error number to text). So now I have a powerful tool in addition to unlink in my tool box to cope with the kluge. In Linux, I will use unlink, but in the kluge, I will probably use my ApiDeleteFile. It never hurts to have enough tools. -T Me wonders why Windows programmers do not tear all their hair out.
Re: need native call help
>From unlink's documentation: If the file to be deleted does not exist, the routine treats it as success. So trying to delete a file that isn't there, doesn't have an error, which is kind of neat, but that is a difference from native delete. -y On Wed, Apr 17, 2024 at 8:50 AM yary wrote: > What does the windows native delete do which you need, that raku's unlink > doesn't > have? > > without unlink $FileName { say "Could not delete $FileName:", > .exception.message > }; > > -y > > > On Wed, Apr 17, 2024 at 2:29 AM ToddAndMargo via perl6-users < > perl6-us...@perl.org> wrote: > >> On 4/16/24 23:25, ToddAndMargo via perl6-users wrote: >> `\\>\` should have been >> `\\?\` >> >>
Re: need native call help
What does the windows native delete do which you need, that raku's unlink doesn't have? without unlink $FileName { say "Could not delete $FileName:", .exception.message }; -y On Wed, Apr 17, 2024 at 2:29 AM ToddAndMargo via perl6-users < perl6-us...@perl.org> wrote: > On 4/16/24 23:25, ToddAndMargo via perl6-users wrote: > `\\>\` should have been > `\\?\` > >
Re: need native call help
On 4/16/24 23:25, ToddAndMargo via perl6-users wrote: `\\>\` should have been `\\?\`
Re: need native call help
On 4/16/24 20:57, ToddAndMargo via perl6-users wrote: $LongName = $FileName; if $FileName.chars >= MAX_PATH { $LongName = Q[\\?\] ~ $FileName; } What the about is all about is that MAX_PATH, which limits the file name to 260 characters, can go up to 32,767 wide characters, prepend "\\?\" to the path. I altered the above line since posting to: $LongName = $FileName; if $FileName.chars >= MAX_PATH && not $FileName.starts-with( Q[\\?] ) { $LongName = Q[\\?\] ~ $FileName; } in case I forget that my module prepends the `\\>\` if I exceed MAX_PATH
Re: need native call help
On 4/16/24 18:43, ToddAndMargo via perl6-users wrote: On 4/16/24 01:21, ToddAndMargo via perl6-users wrote: Hi All, Windows 11 It has been so long that I have done one of these that my brain is seizing. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilea C++ BOOL DeleteFileA( [in] LPCSTR lpFileName ); Would some kind soul please show me how to do this again? Many thanks, -T I got a good night's sleep and my head unfroze. I figured it out. I will post back how in a few days or so. -T Hi All, https://docs.raku.org/language/nativecall is a wonderful documeht, but as far as I can tell, they do not breakdown how to make an API call. They expect you to already know how to do it. So not for the beginners. This is the code I came up with. There is a lot of the my libraries missing from this, if you want them, I can eMail them to you. I am only posting this so you can get the idea of how to do this: -T # unit module NativeDelete; # NativeDelete.rakumod #`{ Delete a filed directory with the Windows DeleteFileA function (fileapi.h) API with NativeCall. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilea https://docs.raku.org/language/nativecall To use, place the following at the top of your program: use NativeDelete :ApiDeleteFile; use NativeCall; use NativeConstants; use NativeConvert :to-UTF8-c-str; use WinErr :WinGetLastError, :WinFormatMessage; Test one liner: Note: in Windows Explorer, right click on the file, left click on copy as path, then paste the entire path. Note the `\\?\` at the beginning for long file names. K:\Windows\NtUtil>echo abc > eraseme.txt && raku -I. -e "use NativeDelete :ApiDeleteFile; say ApiDeleteFile( Q[eraseme.txt] )" && type eraseme.txt OK The system cannot find the file specified. K:\Windows\NtUtil>echo abc > eraseme.txt && raku -I. -e "use NativeDelete :ApiDeleteFile; say ApiDeleteFile( Q[eraseme2.txt] )" && type eraseme.txt The system cannot find the file specified. abc raku -I. -e "use NativeDelete :ApiDeleteFile; say ApiDeleteFile( Q[\\?\D:\MyDocsBackup\backup2\Mozilla 2024-04-15 21;14;31 (Full)\Firefox\Profiles\pj0elosu.default-release\storage\default\https+++505991220932649.webpush.freshchat.com^partitionKey=%28https%2Cbid13.com%29\cache\morgue\114\{7cccd5e9-a7aa-4349-a2e9-569baf007272}.final] );" OK } use NativeCall; use NativeConstants; use NativeConvert :to-UTF8-c-str; use WinErr :WinGetLastError, :WinFormatMessage; sub DeleteFileA( #`{ C++ BOOL DeleteFileA( [in] LPCSTR lpFileName ); } CArray[uint8] $lpFileName ) is native("Kernel32.dll") is symbol("DeleteFileA") returns BOOL { * }; sub ApiDeleteFile( Str $FileName ) returns Str is export( :ApiDeleteFile ) { #`{ $FileName is the file name and optional path path Format: Q[D:\NtUtil\eraseme.txt] Note the backslashes. Returned "OK" if successful or the error message if not Syntax C++ BOOL DeleteFileA( [in] LPCSTR lpFileName ); DLL Kernel32.dll Return value If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error information, call GetLastError. By default, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, prepend "\\?\" to the path. If using `\\?\` you must use the full path. } my DWORD $LastError = 0; my Str $WinErrorMsg = "OK"; my BOOL $RtnValue= 1; my Str $LongName= ""; $LongName = $FileName; if $FileName.chars >= MAX_PATH { $LongName = Q[\\?\] ~ $FileName; } my CArray[uint8] $lpFileName = to-UTF8-c-str( $LongName ); $RtnValue = DeleteFileA( $lpFileName ); sub GetLastError() is native("Kernel32") is symbol("GetLastError") returns DWORD { * }; if $RtnValue == 0 { $LastError = GetLastError(); $WinErrorMsg = WinFormatMessage( $LastError ); } return $WinErrorMsg; }
Re: need native call help
On 4/16/24 01:21, ToddAndMargo via perl6-users wrote: Hi All, Windows 11 It has been so long that I have done one of these that my brain is seizing. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilea C++ BOOL DeleteFileA( [in] LPCSTR lpFileName ); Would some kind soul please show me how to do this again? Many thanks, -T I got a good night's sleep and my head unfroze. I figured it out. I will post back how in a few days or so. -T