Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Compilación condicional (https://www.clubdelphi.com/foros/showthread.php?t=86163)

santiago14 26-06-2014 03:23:16

Compilación condicional
 
Buenas, tengo un dilema.
Resulta que tengo que incluir una unit si el ejecutable está corriendo en Win7 o Win8, caso contrario no se incluye.
Tengo entendido que se hace con los condicionales.
¿Alguien me puede dar una mano? Gracias.

Código Delphi [-]
{$IfDef DefName} //Esto debería indicarme si estoy en Win7 o Win8 o en ninguno.
 thinfinity,
 {$Else}
 system, controls, ...
 {$EndIf}

Al González 26-06-2014 04:58:42

Hola Santiago.

Las directivas de compilación sirven para indicar cómo debe ser generado (compilado) el programa ejecutable. Una vez obtenido éste, será el mismo programa lo instales en donde lo instales. Si deseas un comportamiento diferente de la aplicación según el sistema operativo donde corra, entonces necesitarás añadir instrucciones que verifiquen en qué versión de Windows se encuentra y, mediante tradicionales "Ifs", separar las sentencias que deben ser ejecutadas en unas versiones del sistema operativo de las que deben ser ejecutadas en otras.

Una alternativa a lo anterior sería definir un símbolo condicional en las opciones del proyecto (entrada Conditional defines), sin dejar de usar directivas de compilación $IfDef. El símbolo lo pondrías o lo quitarías, según desees generar un ejecutable para unas versiones de Windows o para otras.

No ando muy lúcido este día, pero ojalá te haya servido de algo mi intervención.

Un cordial saludo. :)

nlsgarcia 26-06-2014 07:45:12

santiago14,

Cita:

Empezado por santiago14
...tengo que incluir una unit si el ejecutable está corriendo en Win7 o Win8...

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ActiveX, ComObj;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetWindowsVersion : String;
const
  wbemFlagForwardOnly = $00000020;

var
  FSWbemLocator : OLEVariant;
  FWMIService : OLEVariant;
  FWbemObjectSet : OLEVariant;
  FWbemObject : OLEVariant;
  oEnum : IEnumvariant;
  iValue : LongWord;
  SQLWMI : String;

begin

  // Obtiene Acceso a WMI
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');

  // Obtiene Acceso al NameSpace root\CIMV2 localmente que contiene la Clase Win32_Process
  FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');

  // Contruye la Consulta SQL WMI (WQL) a la Clase Win32_Process
  SQLWMI := 'SELECT * FROM Win32_OperatingSystem';

  // Ejecuta la Consulta
  FWbemObjectSet := FWMIService.ExecQuery(SQLWMI,'WQL',wbemFlagForwardOnly);

  // Interface a los objetos COM de la consulta por medio de enumeración
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;

  // Accesa las propiedades de los objetos de la enumeración
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
     Result := Format('%s %s',[FWbemObject.Caption, FWbemObject.Version]);
     FWbemObject:=Unassigned;
  end

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(GetWindowsVersion);
end;

end.
El código anterior en Delphi 7 permite obtener por medio de WMI (Windows Management Instrumentation) el nombre y la versión del Sistema Operativo Windows instalado.

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetWindowsVersion : String;
var
   OSVersionInfo: TOSVersionInfo;
   MajorVersion, MinorVersion: Integer;

begin

   Result := 'Windows Unknown';

   OSVersionInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);

   if GetVersionEx(OSVersionInfo) then
   begin

      MajorVersion := OSVersionInfo.dwMajorVersion;
      MinorVersion := OSVersionInfo.dwMinorVersion;

      if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
      begin
         if MajorVersion <= 4 then
            Result := Format('%s %d',['Windows NT',MajorVersion])
         else if (MajorVersion = 5) and (MinorVersion = 0) then
            Result := Format('%s %d.%d',['Windows 2000',MajorVersion,MinorVersion])
         else if (MajorVersion = 5) and (MinorVersion = 1) then
            Result := Format('%s %d.%d',['Windows XP',MajorVersion,MinorVersion])
         else if (MajorVersion = 6) and (MinorVersion = 0) then
            Result := Format('%s %d.%d',['Windows Vista',MajorVersion,MinorVersion])
         else if (MajorVersion = 6) and (MinorVersion = 1) then
            Result := Format('%s %d.%d',['Windows 7',MajorVersion,MinorVersion])
         else if (MajorVersion = 6) and (MinorVersion = 2) then
            Result := Format('%s %d.%d',['Windows 8',MajorVersion,MinorVersion])
      end;

   end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(GetWindowsVersion);
end;

end.
El código anterior en Delphi 2010 permite obtener el nombre y la versión del Sistema Operativo Windows instalado.

Nota: En Delphi 7, el código propuesto identifica erróneamente el SO Windows 7 x32 y x64 como Windows XP.

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetWindowsVersion : String;
var
   OSVersion : TOSVersion;
begin
   Result := Format('%s %d.%d Build %d',[OSVersion.Name,
                                         OSVersion.Major,
                                         OSVersion.Minor,
                                         OSVersion.Build]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(GetWindowsVersion);
end;

end.
El código anterior en Delphi XE6 permite obtener el nombre y la versión del Sistema Operativo Windows instalado.

Revisa esta información:
Espero sea útil :)

Nelson.

santiago14 26-06-2014 15:20:47

Gracias nlsgarcia, yo creo que sí sirve.
Me explico mejor.

Hay una unit que uso, pero solamente ha sido desarrollada para Win8, si compilo en DelphiXE5 sobre Win8 y lo ejecuto , lo hace sin problemas.
Cuando llevo ese ejecutable a otra máquina (XP, Win7), no se ejecuta y devuelve un error.
La idea es que cuando esté corriendo en cierto sistema operativo, Win8, le dé bolilla a esa unit, que está en uses claro, y cuando esté corriendo en otro, no. No se si entiende. Lo mismo vale para los objetos, que están dentro del código, que son de esa unit.
Ahora que lo veo, no se si por el lado de las condicionales la cosa se encamina.

Supongo que se puede combinar lo que pusiste con esta explicación.
Un detalle mas, a esa unit la debo poner en la lista de unit del program. :mad::(

duilioisola 26-06-2014 18:35:40

Con lo que te han explicado, supongo que sería algo así:
Código Delphi [-]
unit CosasParaWindows8;
...
implementatin
funtion DevuelveCosaEspecial(...);
begin
   if (EsWindows8) then
   begin
      ...
   end
   else
      Return -1; // error
end;

La otra opción es:

Código Delphi [-]
funtion EstoUtilizaAlgoDeWindows8(...);
begin
   ...
   if (EsWindows8) then
      VariableEspeciaal := DevuelveCosaEspecial(...)...
   else
      VariableEspeciaal := Obtengo_el_valor_de_otra_manera;   
   ...   
end;

nlsgarcia 26-06-2014 20:50:07

santiago14,

Cita:

Empezado por santiago14
...Hay una unit que uso, pero solamente ha sido desarrollada para Win8...en Delphi XE5 sobre Win8...sin problemas...Cuando llevo ese ejecutable a otra máquina (XP, Win7), no se ejecuta...

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses UWindowsX, UWindows8;

function GetWindowsVersion : Boolean;
var
   OSVersion : TOSVersion;
begin
   if Copy(OSVersion.Name,1,9) = 'Windows 8' then
      Result := True
   else
      Result := False;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   if GetWindowsVersion then
      UWindows8.Msg  // Se ejecuta si el OS es Windows 8
   else
      UWindowsX.Msg; // Se ejecuta si el OS es una versión diferente a Windows 8
end;

end.
El código anterior en Delphi XE6, ejecuta el procedimiento Msg en función de si el Sistema Operativo es Windows 8 o es otro Sistema Operativo Windows.

Espero sea útil :)

Nelson.

escafandra 26-06-2014 22:50:38

Para dar más información, revisa la API GetVersionEx y la estructura OSVERSIONINFO


Código Delphi [-]
function IsWin8: boolean;
var
  VerInfo: TOSVersioninfo;
begin
  VerInfo.dwOSVersionInfoSize:= SizeOf(TOSVersionInfo);
  GetVersionEx(VerInfo);
  Result:= (VerInfo.dwMajorVersion >= 6) and (VerInfo.dwMinorVersion >= 2);
end;

Nota importante:
El código anterior dará WinXP(5.1) si corres por ejemplo delphi7 en Win8 en modo de compatibilidad WinXP durante el debug, pero la aplicación ya compilada reconocerá Win8 sin error


Saludos.

nlsgarcia 27-06-2014 02:54:29

santiago14,

Nota: El segundo código del Msg #3 (Basado en la API GetVersionEx) si es ejecutado en Delphi 7 en modo Debug, identifica erróneamente el SO Windows Vista, Windows 7 y Windows 8 como Windows XP, si es ejecutado directamente desde el ejecutable funcionara correctamente según lo esperado.

Nelson.


La franja horaria es GMT +2. Ahora son las 13:08:14.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi