joi, 21 februarie 2013

FreePascal/Lazarus - size of executable file

After compiling with Lazarus, the executable file is VERY large. To reduce it's size, I did the following:

Linux (OpenSUSE)
1) Install upx package if you don't have it (YaST > Software Management > Search for upx and install)
2) Open terminal (in Dolphin, right-click > Actions > Open terminal here)
3) Run the following commands:
      strip --strip-all Program      (! Linux is case sensitive)
      upx -9 Program                  (! Linux is case sensitive)
The size of "Program" was reduced from 21580 KB to 1276 KB

"Program" is the name of the executable file in my case

And beacause Lazarus is cross-platform...
Windows (W7)
1) Start command prompt
2) Move to the application's directory (in my case: cd c:\Program\)
3) Run the following commands:
      strip --strip-all program.exe
      upx -9 program.exe
The size of "program.exe" was reduced from 14405 KB to 613 KB

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