0

I am using Delphi 7 Pro and need to get Win32MajorVersion and Win32MinorVersion, in order to diferenciate between Windows XP, Vista, 7, 8, 8.1 and 10.

After several hours researching (english is not my native language, sorry), I understood that I needed to change the manifest file for supporting Windows 8.1 and 10. Here is what I got:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="WinApp" version="11.0.2804.9245" processorArchitecture="*"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="False"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
    <application> 
      <!-- Windows 10 --> 
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
      <!-- Windows 8.1 -->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      <!-- Windows Vista -->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
      <!-- Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <!-- Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    </application> 
  </compatibility>
</assembly>

But even after including this manifest, Win32MajorVersion and Win32MinorVersion still give me wrong information on Windows 8.1 and 10.

Please, what am I doing wrong?

PS. I found other SOF posts with other tecniques for not using the manifest file, like using WMI, the Windows registry, etc., but for my purposes I think the manifest will be the most simple and effective way.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Guybrush
  • 1,575
  • 2
  • 27
  • 51
  • most simply call `RtlGetVersion` or `RtlGetNtVersionNumbers` and not need something hardcode in manifest – RbMm Oct 19 '19 at 17:53
  • @RbMm please, can you answer with the simplest code example of `RtlGetVersion`, so I can test and accept the answer? – Guybrush Oct 19 '19 at 18:05
  • `RTL_OSVERSIONINFOW ovi = { sizeof(ovi)}; if (0 <= RtlGetVersion(&ovi)) { DbgPrint("%u.%u\n", ovi.dwMajorVersion, ovi.dwMinorVersion); }` – RbMm Oct 19 '19 at 18:11
  • I am using Delphi 7, but I think I got a functional code. Must I add it as an observation in the post question? Or must I answer my own question? Despite it worked, I am not sure it is 100% correct. – Guybrush Oct 19 '19 at 18:40
  • question like this (how get os version) already asked here many time. *I am not sure it is 100% correct.* - why ? – RbMm Oct 19 '19 at 18:44
  • I do not know if I was using the wrong search words, but couldn't find a complete solution (for Delphi 7) anywhere. I will add my solution in a observation, so maybe it help other people. Thank you! – Guybrush Oct 19 '19 at 18:48
  • `ZeroMemory(@OS, SizeOf(OS));` - you not need this (not error but and not need), `OS.dwOSVersionInfoSize := SizeOf(OS);` is enough, in rest how i can understand delphi - correct – RbMm Oct 19 '19 at 18:58
  • Yes, I am creating a unit for using these information, and just realized the same. Thank you again! – Guybrush Oct 19 '19 at 19:26
  • 1
    I've rolled back your edit. It is not appropriate here to edit the solution into your question. If you've found a solution you'd like to share, do so by writing an answer in the space below intended for that purpose. See [Can I answer my own question?](http://stackoverflow.com/help/self-answer) for more information. – Ken White Oct 20 '19 at 00:46

1 Answers1

0

Based on RbMm comment and an aswer from Mr. Remy Lebeau, I researched some more and created this solution bellow. Despite it is working (for Delphi 7), maybe requires some improvement. Hope it help other people with same requirements. Thanks!

procedure TForm1.Button1Click(Sender: TObject);
type
  _OSVERSIONINFOEXW = record
    dwOSVersionInfoSize: DWORD;
    dwMajorVersion: DWORD;
    dwMinorVersion: DWORD;
    dwBuildNumber: DWORD;
    dwPlatformId: DWORD;
    szCSDVersion: array [0..127] of WCHAR;
    wServicePackMajor: WORD;
    wServicePackMinor: WORD;
    wSuiteMask: WORD;
    wProductType: BYTE;
    wReserved: BYTE;
  end;
  RTL_OSVERSIONINFOEXW = _OSVERSIONINFOEXW;
  pfnRtlGetVersion = function(var RTL_OSVERSIONINFOEXW): LongInt; stdcall;
var
  OS: RTL_OSVERSIONINFOEXW;
  RtlGetVersion: pfnRtlGetVersion;
begin
  @RtlGetVersion := GetProcAddress(GetModuleHandle('ntdll.dll'), 'RtlGetVersion');
  if Assigned(RtlGetVersion) then
  begin
    ZeroMemory(@OS, SizeOf(OS));
    OS.dwOSVersionInfoSize := SizeOf(OS);
    if (RtlGetVersion(OS) = 0) then
    begin
      Memo1.Lines.Add('MajorVersion: ' + IntToStr(OS.dwMajorVersion));
      Memo1.Lines.Add('MinorVersion: ' + IntToStr(OS.dwMinorVersion));
      Memo1.Lines.Add('BuildNumber: ' + IntToStr(OS.dwBuildNumber));
      Memo1.Lines.Add('ServicePackMajor: ' + IntToStr(OS.wServicePackMajor));
      Memo1.Lines.Add('ServicePackMinor: ' + IntToStr(OS.wServicePackMinor));
      Memo1.Lines.Add(OS.szCSDVersion);
    end;
  end;
end;
Guybrush
  • 1,575
  • 2
  • 27
  • 51