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;
}