Quantcast
Channel: Planet Object Pascal
Viewing all articles
Browse latest Browse all 1725

Delphi Haven: Programmatically shutting down, restarting, sleeping or logging off on OS X

$
0
0

Browsing StackOverflow, I came across a question asking how to programmatically shut down the computer in Delphi when targeting OS X. Mysteriously, the question has been met with four downvotes as I write this, leaving it ‘on hold as off-topic’ until the darstardly questioner stops thinking a programmer’s Q&A site is a proper place for programming questions or something.

Anyhow, with respect to the question, one easy way to do the deed is to use a Cocoa NSAppleScript object to run the following piece of AppleScript:

tell application "Finder" to shut down

As desired, ‘to shut down’ can be replaced with ‘to restart’, ‘to sleep’ or ‘to log out’.

Now in Delphi, NSAppleScript (or more exactly, a wrapper interface type for NSAppleScript) is declared in the Macapi.Foundation unit. Alas, but this is misdeclared, or at least was when I last looked (see here– if someone wants to confirm this is still the case in the latest and greatest, please do in the comments). As such, you need to fix the declaration before using it. On the other hand, fixing it is easy:

uses
  Macapi.ObjectiveC, Macapi.CocoaTypes, Macapi.Foundation;

type
  NSAppleScript = interface(NSObject)
    ['{0AB1D902-25CE-4F0B-A3BE-C4ABEDEB88BC}']
    function compileAndReturnError(errorInfo: Pointer): Boolean; cdecl;
    function executeAndReturnError(errorInfo: Pointer): Pointer; cdecl;
    function executeAppleEvent(event: NSAppleEventDescriptor; error: Pointer): Pointer; cdecl;
    function initWithContentsOfURL(url: NSURL; error: Pointer): Pointer; cdecl;
    function initWithSource(source: NSString): Pointer; cdecl;
    function isCompiled: Boolean; cdecl;
    function source: NSString; cdecl;
  end;
  TNSAppleScript = class(TOCGenericImport<NSAppleScriptClass, NSAppleScript>)  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Script: NSAppleScript;
  Error: Pointer;
begin
  Error := nil;
  Script := TNSAppleScript.Wrap(TNSAppleScript.Alloc.initWithSource(
    NSSTR('tell application "Finder" to shut down')));
  try
    if Script.executeAndReturnError(Error) = nil then
      raise EOSError.Create('AppleScript macro failed');
  finally
    Script.release;
  end;
end;


Viewing all articles
Browse latest Browse all 1725

Trending Articles