-4

I am having a project to show Windows Version with Edition Type strting from "Windows 95" to "Windows 8" using Delphi XE2. Firstly I have tried "TOSVersion" Function. But the problem is :

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
  VersionNameOfOperatingSystem : String;
begin
  VersionNameOfOperatingSystem := TOSVersion.Name;
  Edit01.Text := VersionNameOfOperatingSystem;
end

Shows only "Windows" in Windows 8 Environment" and another problem is that Ii can not detect "Windows Edition". Then I ahve tried "GetProductInfo" Function. But here is another problem :

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 0, 0, 0, @rpt) then Edit02.Text :=IntToStr(rpt);
end

and

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 1, 0, 0, @rpt) then Edit02.Text :=IntToStr(rpt);
end

and

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 2, 0, 0, @rpt) then Edit02.Text :=IntToStr(rpt);
end

and

function GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion,
dwSpMinorVersion: DWORD; pdwReturnedProductType: PDWORD): BOOL stdcall;
external kernel32;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
rpt: cardinal;
begin
  if GetProductInfo(6, 2, 2, 2, @rpt) then Edit02.Text :=IntToStr(rpt);
end

produces the same result If I run the compiled exe file in Windows Vista Enterprise SP2 and the same can not be used earlier version of Windows. If I call "TOSVersion" as follows

begin
  TOSVersion.Platform of
    pfWindows : 
      begin
      .
      .
      .
      .
      end
    else
      beging
      .
      .
      .
      end
end;

and the call "GetProductInfo" then I am getting "Error" telling that both can not called simutaneously. At last I have try "OSVERSIONINFO Structure" to identify whether it is "Server" or not and "GetVersionEx Function" for "Windows XP Edition Type". I am totally confused how to start my programming. There are so many experienced coder in this forum. Anybody can write down the complete program. I have googled it but all the available programs are upto "Windows 7" not updated. And one availabe in this forum is also upto "Windows 7" and not updated. Please don't tell "We cannot sit at your keyboard and type the code for you". Please help me.

Rubi Halder
  • 583
  • 3
  • 12
  • 24
  • You are asking for us to write a complete program to solve your exact problem. That's the very definition of a question that is too localized. All the information is in your other recent questions. – David Heffernan Mar 28 '13 at 08:27
  • Again I have tried Ken's Code and I am getting error as "[DCC Warning] Unit1.pas(148): W1036 Variable 'dwOSMajorVersion' might not have been initialized" "[DCC Warning] Unit1.pas(148): W1036 Variable 'dwOSMinorVersion' might not have been initialized" "[DCC Warning] Unit1.pas(148): W1036 Variable 'dwSpMajorVersion' might not have been initialized" "[DCC Warning] Unit1.pas(148): W1036 Variable 'dwSpMinorVersion' might not have been initialized". But I am also unable to show the string of "Result" and "tmpStr". If I define "Edit1.Text :=Result; and Edit2.Text:=tmpStr; gives error. – Rubi Halder Mar 28 '13 at 09:14
  • OK, I tried to compile Ken's code. It doesn't compile. It is poor. Here's a version that does compile. I've not tested it comprehensively: http://pastebin.com/RZd1Ag4u – David Heffernan Mar 28 '13 at 09:37
  • Code in my old post fixed (note to self: never post code here you've found but never compiled). Now compiles, and has minimal support for Windows 8. It returns `Windows 7 Unknown Product` for some reason on Win7 Pro (OEM) that I haven't tracked down yet. – Ken White Mar 28 '13 at 13:28
  • Please tell me what is actually doing "NTBres" and "BRes" in Ken's Code. – Rubi Halder Apr 03 '13 at 09:36

1 Answers1

2

It seems to me that all your recent questions have been related to the following problem:

  1. You want to get the full product name of the operating system. Various example codes that you have tried have flaws. For example, many of the samples you have tried do not recognise Windows 8.
  2. You want to know the product type. You wish to detect the Ultimate editions.

I suggest that you use WMI to do this. That will future proof your code so that it works on as yet unreleased versions of Windows.

For my WMI code, I shamelessly re-used the WMI expert RRUZ's code from this answer: How do I use WMI with Delphi without drastically increasing the application's file size?

unit SimpleWMI;

interface

uses
  SysUtils, ActiveX, ComObj, Variants;

function GetWMIprops(const wmiHost, root, wmiClass: string; const wmiProps: array of string): TArray<string>;

implementation

function GetWMIprops(const wmiHost, root, wmiClass: string; const wmiProps: array of string): TArray<string>;
var
  objWMIService: OLEVariant;
  colItems: OLEVariant;
  colItem: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;

  function GetWMIObject(const objectName: String): IDispatch;
  var
    chEaten: Integer;
    BindCtx: IBindCtx;
    Moniker: IMoniker;
  begin
    OleCheck(CreateBindCtx(0, BindCtx));
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
  end;

var
  i: Integer;

begin
  objWMIService := GetWMIObject(Format('winmgmts:\\%s\%s', [wmiHost, root]));
  colItems := objWMIService.ExecQuery(Format('SELECT * FROM %s', [wmiClass]), 'WQL', 0);
  oEnum := IUnknown(colItems._NewEnum) as IEnumvariant;
  SetLength(Result, Length(wmiProps));
  while oEnum.Next(1, colItem, iValue) = 0 do
    for i := 0 to high(wmiProps) do
      Result[i] := colItem.Properties_.Item(wmiProps[i], 0);
end;

end.

So now you can solve your problem with this simple program:

program OSVersionDemo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows,
  ActiveX,
  SimpleWMI in 'SimpleWMI.pas';

function IsUltimateEdition(ProductType: DWORD): Boolean;
begin
  Result := ProductType in [PRODUCT_ULTIMATE,PRODUCT_ULTIMATE_N,PRODUCT_ULTIMATE_E];
end;

var
  PropValues: TArray<string>;
  ProductType: DWORD;

begin
  CoInitialize(nil);
  try
    PropValues := GetWMIprops('.', 'root\CIMV2', 'Win32_OperatingSystem', ['Caption', 'Version', 'OperatingSystemSKU']);
    Writeln('OS Name: ' + PropValues[0]);
    Writeln('Version: ' + PropValues[1]);
    ProductType := StrToInt(PropValues[2]);
    Writeln('Ultimate edition: ' + BoolToStr(IsUltimateEdition(ProductType), True));

    Readln;
  finally
    CoUninitialize;
  end;
end.

On my machine the output is:

OS Name: Microsoft Windows 7 Professional
Version: 6.1.7601
Ultimate edition: False

The Win32_OperatingSystem class has loads more information. So if you want to get at the service pack information, ask for the CSDVersion property. Like this:

PropValues := GetWMIprops('.', 'root\CIMV2', 'Win32_OperatingSystem', ['Caption', 'Version', 'OperatingSystemSKU', 'CSDVersion']);
Writeln('OS Name: ' + Trim(PropValues[0]) + ' ' + Trim(PropValues[3]));
Writeln('Version: ' + PropValues[1]);
ProductType := StrToInt(PropValues[2]);
Writeln('Ultimate edition: ' + BoolToStr(IsUltimateEdition(ProductType), True));

I hope this provides enough information for you to fill out what you actually need for your problem.

Although you say that you want to support Windows 95, 98 and ME, do be aware that programs produced with Unicode versions of Delphi (XE2 for example) do not run on those ancient systems.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490