https://developer.apple.com/documentati ... endmessage
AESendMessage
AESendMessage
Any PB example for AESendMessage available? As of now not 
https://developer.apple.com/documentati ... endmessage
			
			
									
									
						https://developer.apple.com/documentati ... endmessage
Re: AESendMessage
Do you have any example code in Objective-C or Swift of what you want to do with the command ?Rinzwind wrote:Any PB example for AESendMessage available? As of now not
Windows (x64)
Raspberry Pi OS (Arm64)
						Raspberry Pi OS (Arm64)
Re: AESendMessage
I do have a C-example
Even the 'abcd' AEEvents is driving me crazy in PB. How to easily handle those..
The example code runs fine btw.
For what it's worth, here some definitions I played with:
How to easily set descriptorType to one of the predefined constants? Guess PB doesn't like that (overflow compiler error).
			
			
									
									
						Code: Select all
#include <stdio.h> 
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>
static OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend);
int main(void)
{
	const int bufferSize = 256;
	OSStatus error = noErr;
	char select [bufferSize];
	printf("1: Restart computer\n");
	printf("2: Shutdown computer\n");
	printf("3: Logout computer\n");
	printf("4: Sleep computer\n");
	printf("5: Quit All\n");
	printf("q: quit program\n");
	printf("please enter choice:\n");fflush(stdout);
	fgets(select, bufferSize, stdin);
	switch (select[0])
	{
		 case '1':
			//sending restart event to system
			error = SendAppleEventToSystemProcess(kAERestart);
			if (error == noErr)
				{printf("Computer is going to restart!\n");}
			else
				{printf("Computer wouldn't restart\n");}
		 break;
		
		 case '2':
			//sending shutdown event to system
			error = SendAppleEventToSystemProcess(kAEShutDown);
			if (error == noErr)
				{printf("Computer is going to shutdown!\n");}
			else
				{printf("Computer wouldn't shutdown\n");}
		 break;
		 case '3':
			//sending logout event to system
			error = SendAppleEventToSystemProcess(kAEReallyLogOut);
			if (error == noErr)
				{printf("Computer is going to logout!\n");}
			else
				{printf("Computer wouldn't logout");}
		 break;
		 case '4':
			//sending sleep event to system
			error = SendAppleEventToSystemProcess(kAESleep);
			if (error == noErr)
				{printf("Computer is going to sleep!\n");}
			else
				{printf("Computer wouldn't sleep");}
		break;				
	};
	return(0);
}
OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend)
{
	AEAddressDesc targetDesc;
	static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess };
	AppleEvent eventReply = {typeNull, NULL};
	AppleEvent appleEventToSend = {typeNull, NULL};
	OSStatus error = noErr;
	error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, 
											sizeof(kPSNOfSystemProcess), &targetDesc);
	if (error != noErr)
	{
		return(error);
	}
	
	error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, 
				   kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend);
	AEDisposeDesc(&targetDesc);
	if (error != noErr)
	{
		return(error);
	}
	//error = AESend(&appleEventToSend, &eventReply, kAENoReply, 
	//			  kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
	error = AESendMessage(&appleEventToSend, &eventReply,
				                          kAENormalPriority, 0);//kAEDefaultTimeout);
	AEDisposeDesc(&appleEventToSend);
	if (error != noErr)
	{
		return(error);
	}
	AEDisposeDesc(&eventReply);
	return(error); 
}
The example code runs fine btw.
For what it's worth, here some definitions I played with:
Code: Select all
ImportC ""
  AECreateDesc(typeCode, *dataPtr, dataSize,  *result)
  AECreateAppleEvent(theAEEventClass, theAEEventID,  *target, returnID, transactionID, *result)
  AESendMessage(*event, *reply, sendMode, timeOutInTicks.l)
  AEDisposeDesc(theAEDesc)
EndImport
Structure ProcessSerialNumber
  HighLongOfPSN.l
  LowLongOfPSN.l
EndStructure
Structure AEDesc
  descriptorType.a[4]
  dataHandle.l
EndStructure
#typeNull = 'null'
#typeProcessSerialNumber = 'psn '
#kCoreEventClass = 'aevt'
#kAutoGenerateReturnID         = -1
#kAnyTransactionID             = 0 
#kAENormalPriority             = $00000000
#kAEDefaultTimeout             = -1
#kAEShutDown                   = 'shut'
#kAESleep                      = 'slep'
#noErr = 0
Re: AESendMessage
I'm doing something wrong but I don't know what.Rinzwind wrote:Even the 'abcd' AEEvents is driving me crazy in PB. How to easily handle those..
The example code runs fine btw.
I thought it had to be something like the code below but it keeps crashing.
Edit:
See post below for the updated working code
viewtopic.php?p=541150#p541150
Code: Select all
#noErr                    = 0
#kAnyTransactionID        = 0
#kAENormalPriority        = 0
#kAENoReply               = 1
#kSystemProcess           = 1
#kAEDefaultTimeout        = -1
#kAutoGenerateReturnID    = -1
#kAERestart               = $72657374; 'rest'
#kAEShutDown              = $73687574; 'shut'
#kAEReallyLogOut          = $726C676F; 'rlgo'
#kAESleep                 = $736C6570; 'slep'
#typeNull                 = $6E756C6C; 'null'
#typeProcessSerialNumber  = $70736E20; 'psn '
#kCoreEventClass          = $61657674; 'aevt'
ImportC ""
  AECreateDesc(typeCode, *dataPtr, dataSize, *result)
  AECreateAppleEvent(theAEEventClass, theAEEventID, *target, returnID, transactionID, *result)
  AEDisposeDesc(*theAEDesc)
  AESend(*event, *reply, sendMode, sendPriority, timeOutInTicks, *idleProc, *filterProc)
  AESendMessage(*event, *reply, sendMode, timeOutInTicks)
EndImport
Structure ProcessSerialNumber
  HighLongOfPSN.l
  LowLongOfPSN.l
EndStructure
Structure AEDesc
  desctiptorType.l
  dataHandle.l
EndStructure
Procedure.l SendAppleEventToSystemProcess(EventToSend.l)
  Protected.ProcessSerialNumber kPSNOfSystemProcess
  Protected.AEDesc targetDesc, eventReply, appleEventToSend
  Protected.l error
  
  kPSNOfSystemProcess\LowLongOfPSN = #kSystemProcess
  eventReply\desctiptorType = #typeNull
  appleEventToSend\desctiptorType = #typeNull
  
  error = AECreateDesc(#typeProcessSerialNumber, @kPSNOfSystemProcess, SizeOf(kPSNOfSystemProcess), @targetDesc)
  If error
    ProcedureReturn error
  EndIf
  
  error = AECreateAppleEvent(#kCoreEventClass, EventToSend, @targetDesc, #kAutoGenerateReturnID, #kAnyTransactionID, @appleEventToSend)
  AEDisposeDesc(@targetDesc)
  If error
    ProcedureReturn error
  EndIf
  
  error = AESendMessage(@appleEventToSend, @eventReply, #kAENormalPriority, 0)
  ;error = AESend(@appleEventToSend, @eventReply, #kAENoReply, #kAENormalPriority, #kAEDefaultTimeout, #Null, #Null)
  AEDisposeDesc(@appleEventToSend)
  If error
    ProcedureReturn error
  EndIf  
  
  AEDisposeDesc(@eventReply)
  
  ProcedureReturn error
  
EndProcedure
SendAppleEventToSystemProcess(#kAESleep)
					Last edited by wilbert on Wed Aug 28, 2019 3:44 pm, edited 1 time in total.
									
			
									Windows (x64)
Raspberry Pi OS (Arm64)
						Raspberry Pi OS (Arm64)
Re: AESendMessage
Thanks so far..
Huh?! moment:
After the line...
error = AECreateDesc(#typeProcessSerialNumber, @kPSNOfSystemProcess, SizeOf(kPSNOfSystemProcess), @targetDesc)
...the field eventReply\desctiptorType is changed from 1853189228 to 1?
			
			
									
									
						Huh?! moment:
After the line...
error = AECreateDesc(#typeProcessSerialNumber, @kPSNOfSystemProcess, SizeOf(kPSNOfSystemProcess), @targetDesc)
...the field eventReply\desctiptorType is changed from 1853189228 to 1?
Re: AESendMessage
That's great. You found the problem. It is working now.Rinzwind wrote:Huh?! moment:
Code: Select all
#noErr                    = 0
#kAnyTransactionID        = 0
#kAENormalPriority        = 0
#kAENoReply               = 1
#kSystemProcess           = 1
#kAEDefaultTimeout        = -1
#kAutoGenerateReturnID    = -1
#kAERestart               = $72657374; 'rest'
#kAEShutDown              = $73687574; 'shut'
#kAEReallyLogOut          = $726C676F; 'rlgo'
#kAESleep                 = $736C6570; 'slep'
#typeNull                 = $6E756C6C; 'null'
#typeProcessSerialNumber  = $70736E20; 'psn '
#kCoreEventClass          = $61657674; 'aevt'
ImportC ""
  AECreateDesc(typeCode, *dataPtr, dataSize, *result)
  AECreateAppleEvent(theAEEventClass, theAEEventID, *target, returnID, transactionID, *result)
  AEDisposeDesc(*theAEDesc)
  AESend(*event, *reply, sendMode, sendPriority, timeOutInTicks, *idleProc, *filterProc)
  AESendMessage(*event, *reply, sendMode, timeOutInTicks)
EndImport
Structure ProcessSerialNumber
  HighLongOfPSN.l
  LowLongOfPSN.l
EndStructure
Structure AEDesc
  desctiptorType.l
  *dataHandle
EndStructure
Procedure.l SendAppleEventToSystemProcess(EventToSend.l)
  Protected.ProcessSerialNumber kPSNOfSystemProcess
  Protected.AEDesc targetDesc, eventReply, appleEventToSend
  Protected.l error
  
  kPSNOfSystemProcess\LowLongOfPSN = #kSystemProcess
  eventReply\desctiptorType = #typeNull
  appleEventToSend\desctiptorType = #typeNull
  
  error = AECreateDesc(#typeProcessSerialNumber, @kPSNOfSystemProcess, SizeOf(kPSNOfSystemProcess), @targetDesc)
  If error
    ProcedureReturn error
  EndIf
  
  error = AECreateAppleEvent(#kCoreEventClass, EventToSend, @targetDesc, #kAutoGenerateReturnID, #kAnyTransactionID, @appleEventToSend)
  AEDisposeDesc(@targetDesc)
  If error
    ProcedureReturn error
  EndIf
  
  error = AESendMessage(@appleEventToSend, @eventReply, #kAENormalPriority, 0)
  ;error = AESend(@appleEventToSend, @eventReply, #kAENoReply, #kAENormalPriority, #kAEDefaultTimeout, #Null, #Null)
  AEDisposeDesc(@appleEventToSend)
  If error
    ProcedureReturn error
  EndIf  
  
  AEDisposeDesc(@eventReply)
  
  ProcedureReturn error
  
EndProcedure
SendAppleEventToSystemProcess(#kAESleep)Windows (x64)
Raspberry Pi OS (Arm64)
						Raspberry Pi OS (Arm64)
Re: AESendMessage
Great it works. Heel erg bedankt voor de hulp.
			
			
									
									
						Re: AESendMessage
Alternative code (macOS 10.11+) ...
			
			
									
									Code: Select all
#typeProcessSerialNumber  = $70736E20; 'psn '
#kCoreEventClass          = $61657674; 'aevt'
#kAERestart               = $72657374; 'rest'
#kAEShutDown              = $73687574; 'shut'
#kAEReallyLogOut          = $726C676F; 'rlgo'
#kAESleep                 = $736C6570; 'slep'
#kAEDefaultTimeout        = -1
#kAENormalPriority        =  0
#kAnyTransactionID        =  0
#kAutoGenerateReturnID    = -1
#NSAppleEventSendNoReply  =  1
Procedure.l SendAppleEventToSystemProcess(EventToSend.l)
  
  Static kPSNOfSystemProcess.q = $100000000
  
  Protected.i target, event, error
  
  target = CocoaMessage(0, 0, "NSAppleEventDescriptor descriptorWithDescriptorType:", #typeProcessSerialNumber, 
                        "bytes:", @kPSNOfSystemProcess, "length:", 8)
  
  event = CocoaMessage(0, 0, "NSAppleEventDescriptor appleEventWithEventClass:", #kCoreEventClass, 
                       "eventID:", EventToSend, "targetDescriptor:", target, 
                       "returnID:", #kAutoGenerateReturnID, "transactionID:", #kAnyTransactionID)
  
  CocoaMessage(0, event, "sendEventWithOptions:", #NSAppleEventSendNoReply, 
               "timeout:", #kAEDefaultTimeout, "error:@", @error)
  
  ProcedureReturn Bool(error = #nil)
  
EndProcedure
SendAppleEventToSystemProcess(#kAESleep)Windows (x64)
Raspberry Pi OS (Arm64)
						Raspberry Pi OS (Arm64)
- robertfern
 - User

 - Posts: 38
 - Joined: Fri Feb 02, 2018 10:33 pm
 - Location: New Jersey
 
Re: AESendMessage
How does one send an AppleEvent to the Finder?
and also how does one send the data to go with the event?
Such as tell application "Finder" to get selection
then get the first item of the selection
and then tell application "Finder" to open information window of I
Applescript is
raw chevron code is 
			
			
									
									and also how does one send the data to go with the event?
Such as tell application "Finder" to get selection
then get the first item of the selection
and then tell application "Finder" to open information window of I
Applescript is
Code: Select all
tell application "Finder"
	set mySelection to selection
	repeat with i in mySelection
		set i to contents of i
		open information window of i
	end repeat
end tellCode: Select all
tell «class capp» "Finder"
	set mySelection to «property sele»
	repeat with i in mySelection
		set i to «property pcnt» of i
		«event aevtodoc» «class iwnd» of i
	end repeat
end tellMac OSX Ventura & Windows 10, PB 6.12
						AppleScript to PB
In case you wanted to use AppleScript directly:
Code: Select all
EnableExplicit
; for simple AppleScripts:
Procedure simpleShell(ShellCommand$, wait = #False)
   Protected shell = RunProgram("/bin/sh","","", #PB_Program_Open|#PB_Program_Write)
   If shell
      WriteProgramStringN(shell,ShellCommand$)
      WriteProgramData(shell,#PB_Program_Eof,0)
      If wait
         While ProgramRunning(shell) : Delay(10) : Wend
      EndIf
      CloseProgram(shell)
   EndIf
EndProcedure
; for AppleScripts:
Structure daResults : Out.s : Err.s : ExC.w : EndStructure
Global Sh.daResults
Procedure shShell(ShellCommand$, AddLF = #False)
   Protected Err$, tmper$, Output$, shell, Exc.w =-1 ; exit code -1 on failed launch
   shell = RunProgram("/bin/sh","","",
      #PB_Program_Open|#PB_Program_Write|#PB_Program_Read|#PB_Program_Error )
   If shell
      WriteProgramStringN(shell,ShellCommand$)
      WriteProgramData(shell,#PB_Program_Eof,0)
      While ProgramRunning(shell)
         If AvailableProgramOutput(shell)
            Output$ + ReadProgramString(shell)
            If AddLF : Output$ + ~"\n" : EndIf
         EndIf
         tmper$ = ReadProgramError(shell)
         If tmper$ : Err$ + tmper$ + ~"\n" : EndIf
      Wend
      Exc = ProgramExitCode(shell) : CloseProgram(shell)
   EndIf
   Sh\Out = Output$ : Sh\Err = Err$ : Sh\ExC = Exc
EndProcedure
; Translates AppleScript code on clipboard to obtain a PB string like below
; AppleScript MUST use TABS to indent. Better compile your AppleScript code, before copying it…
Define MyAScr.s = ~"osascript\n"+
~"set c to the clipboard as string\n"+
~"property dacut : \"\\\\n\\\"+\\r~\\\"\"\n"+
~"set pbt to \"\"\n"+
~"set rc to false -- false = do not remove comments\n"+
~"try\n"+
~"display dialog \"Remove -- Comments?\\r\\rAVOID -- in strings!!!\" buttons {\"Keep\", \"Remove\"} cancel button 1 default button 2\n"+
~"set rc to true\n"+
~"end try\n"+
~"repeat with i in paragraphs of c\n"+
~"set i to i as string\n"+
~"set i to replace_chars(i, tab, \"\") -- editor MUST use TABS to indent...\n"+
~"if rc then -- remove comments\n"+
~"set o to offset of \"--\" in i\n"+
~"if o > 1 then\n"+
~"set i to (characters 1 thru (o - 2) of i) as string\n"+
~"else if o = 1 then\n"+
~"set i to \"\"\n"+
~"end if\n"+
~"end if\n"+
~"if i is not \"\" then\n"+
~"set i to replace_chars(i, \"\\\\\", \"\\\\\\\\\") -- backslash to double backslash\n"+
~"set i to replace_chars(i, \"\\\"\", \"\\\\\\\"\") -- double-quote to backslash double-quote\n"+
~"set pbt to pbt & \"\\\\n\" & i\n"+
~"end if\n"+
~"end repeat\n"+
~"set pbt to \"Define MyAScr.s = ~\\\"osascript\" & pbt & \"\\\"\\r\\r\"\n"+
~"if (count pbt) > 80 then\n"+
~"try\n"+
~"display dialog \"CUT?\" buttons {\"NO\", \"Cut\"} cancel button 1 default button 2\n"+
~"copy replace_chars(pbt, \"\\\\n\", dacut) to pbt\n"+
~"end try\n"+
~"end if\n"+
~"set dla to display dialog \"Set the Clipboard to this?\\r\\rYou can edit here…\" default answer pbt buttons {\"Cancel\", \"Copy\"} cancel button 1 default button 2\n"+
~"set the clipboard to text returned of dla -- set the clipboard to pbt -- no editing\n"+  
~"on replace_chars(this_text, search_string, replacement_string)\n"+
~"local asd\n"+
~"set asd to AppleScript's text item delimiters\n"+
~"set AppleScript's text item delimiters to the search_string\n"+
~"set the item_list to every text item of this_text\n"+
~"set AppleScript's text item delimiters to the replacement_string\n"+
~"set this_text to the item_list as string\n"+
~"set AppleScript's text item delimiters to asd\n"+
~"return this_text\n"+
~"end replace_chars"
simpleShell(~"osascript\ntell app \"Finder\"\nbeep\nend", #True) ; #True = waits until exit
simpleShell("osascript -e beep") ; one word: doesn't even need to be quoted ('beep')
shShell(MyAScr) ; Eventual AppleScript returned output or error will be in Sh\Out, Sh\Err, Sh\ExC
					Last edited by Piero on Thu Jan 30, 2025 4:49 am, edited 3 times in total.
									
			
									
						- robertfern
 - User

 - Posts: 38
 - Joined: Fri Feb 02, 2018 10:33 pm
 - Location: New Jersey
 
Re: AESendMessage
Nice, but I already knew how to do that, but I want to be able to send the AppleEvents directly like the examples here.
** EDIT **
What are the "~" (tilde) character doing in your string concatinations?
			
			
									
									** EDIT **
What are the "~" (tilde) character doing in your string concatinations?
Mac OSX Ventura & Windows 10, PB 6.12
						Re: AESendMessage
You don't need to use AppleEvent to display the information window of a selected file in the finder. You may take a look into my second example which demonstrates how to open the finder, select the logo.png file in the PureBasic.app and display the information window for logo.png.robertfern wrote: Wed Jan 15, 2025 12:19 am How does one send an AppleEvent to the Finder?
and also how does one send the data to go with the event?
Such as tell application "Finder" to get selection
then get the first item of the selection
and then tell application "Finder" to open information window of I
- robertfern
 - User

 - Posts: 38
 - Joined: Fri Feb 02, 2018 10:33 pm
 - Location: New Jersey
 
Re: AESendMessage
OK, but I still would like to know how to send an AppleEvent with data attached. SO I can use the same process to handle other programs and events.
I don't need an aletrnative way to do this. I want to KNOW how it gets done so I can LEARN.
			
			
									
									I don't need an aletrnative way to do this. I want to KNOW how it gets done so I can LEARN.
Mac OSX Ventura & Windows 10, PB 6.12
						Re: AESendMessage
Hope you already found it, anyway it's to use "escape codes", like:robertfern wrote: Wed Jan 15, 2025 7:33 pmWhat are the "~" (tilde) character doing in your string concatinations?
Code: Select all
Debug ~"\n \r \t \\ \" "

