miercuri, 6 februarie 2013

FreePascal: OS detection, system shutdown

I love music. Sometimes I listen to music till I fall asleep, so I need a program that can shut down the computer for me after a while. And because not everybody is using Linux, a cross-platform program would be nice :-)
Problems solved:
 - a function that returns the OS
 - a way to interact with the OS - in my case, sending a simple command (like shutdown)
Once again, many thanks to the Lazarus/FPC community!
The program was tested on OpenSUSE 12.2 and Windows 7. If someone can give the solution for Mac or other OS, he's welcomed!

You need:
 - 1 Form :-)
 - 1 SpeedButton
 - 2 Labels
 - 1 Edit
 - 1 Timer

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, ExtCtrls, process;

type

  { TForm1 }

  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    SpeedButton1: TSpeedButton;
    Timer1: TTimer;
    procedure FormShow(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  timp: integer;
  MyOS: string;
  Comanda: tprocess;

function OSVersion: String;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  try
    timp:=strtoint(edit1.Text);
    label2.Caption:=edit1.Text;
    timer1.Enabled:=true;
  except
    showmessage('Eroare!');
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   timp:=timp-1;
   label2.Caption:=inttostr(timp);
   if timp=0 then
   begin
     if MyOS='Linux' then comanda.CommandLine:='/sbin/shutdown';
     if MyOS='Windows' then comanda.CommandLine:='shutdown -s -t 0';
     comanda.Execute;
   end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  MYOS:=osversion;
  form1.Caption:=MYOS;
  timp:=30;
  label1.Caption:='Minute';
  Label2.Caption:='30';
  edit1.Text:='30';
  comanda:=tprocess.Create(nil);
  timer1.Interval:=60000;
end;

function OSVersion: String;
 var
  osErr: integer;
  response: longint;
begin
  {$IFDEF LCLcarbon}
  OSVersion := 'MacOS';
  {$ELSE}
  {$IFDEF Linux}
  OSVersion := 'Linux';
  {$ELSE}
  {$IFDEF UNIX}
  OSVersion := 'Unix';
  {$ELSE}
  {$IFDEF WINDOWS}
  OSVersion:= 'Windows';
  {$ENDIF}
  {$ENDIF}
  {$ENDIF}
  {$ENDIF}
end;

end.


[UPDATE]
The program worked fine in OpenSUSE 12.2, but 12.3 required root privileges to shutdown the computer. So, a procedure must be rewritten:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  timp:=timp-1;
   label2.Caption:=inttostr(timp);
   if timp=0 then
   begin
     if MyOS='Linux' then
        begin
          comanda.Executable:='/bin/sh';
          comanda.Parameters.Add('-c');
          comanda.Parameters.Add('echo '+parola+' | sudo -S /sbin/shutdown -h now');
          comanda.Execute;
        end;
     if MyOS='Windows' then
        begin
          comanda.CommandLine:='shutdown -s -t 0';
          comanda.Execute;
        end;
   end;
end;


'parola' is a variable that can be supplied in different ways (I used a TEdit component)

[UPDATE]
I've made the source code available here:
https://www.dropbox.com/sh/d5bw7h3j33vmu5t/AAARZeUlm4pvHHJwnqUEn4Jqa?dl=0

 

3 comentarii:

  1. this work for ubuntu too?? can u give me simple way just code to shutdown only

    RăspundețiȘtergere
    Răspunsuri
    1. The simplest way to do it (at a click of a button):

      unit Unit1;

      {$mode objfpc}{$H+}

      interface

      uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, process;

      type

      { TForm1 }

      TForm1 = class(TForm)
      Button1: TButton;
      procedure Button1Click(Sender: TObject);
      private
      { private declarations }
      public
      { public declarations }
      end;

      var
      Form1: TForm1;

      implementation

      {$R *.lfm}

      { TForm1 }

      procedure TForm1.Button1Click(Sender: TObject);
      var parola: string; Comanda: tprocess;
      begin
      parola:='123'; //here you assign your root password; mine is 123, for example
      comanda:=tprocess.Create(nil);
      comanda.Executable:='/bin/sh';
      comanda.Parameters.Add('-c');
      comanda.Parameters.Add('echo '+parola+' | sudo -S /sbin/shutdown -h now');
      comanda.Execute;
      end;

      end.

      Ștergere
  2. I did not test it on Ubuntu, but I did on Mint (Debian-based) and it works. I'm sure it works on Ubuntu as well

    RăspundețiȘtergere