Link to home
Start Free TrialLog in
Avatar of duke63
duke63

asked on

Check registry for operating system and service pack installed

hi,

I want to give users a message in a setup program when they have Windows XP with SP2 installed.
Where can I find this in the registry?

thanks,
axel

Avatar of robert_marquardt
robert_marquardt

Have a look at the Jedi Code Library http://www.sf.net/projects/jcl
It contains among many other things extensive system info functions including the info you search for.
Avatar of duke63

ASKER

Thanks, they have a lot of registry stuff...
But I couldnt find what I exactly need? Have you seen this?
To be more specific.
I have a Setup Programm written in Delphi 5.
Within the installation, a small Intranet Server will be installed.

People who switched to XP2 and avtivated the Firewall might have problems with this.
During the installation process I want to check if they have SP2 installed to give them some advice.

I have XP SP1 but in the Update area also entries with XP2 updates...
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\Windows XP\SP2...

Couldnt find  the right keys???
Here it is:

function GetSPString: string;
var
  VerInfo: TOSVersionInfo;
begin
  result := '';
  try
    VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
    GetVersionEx(VerInfo);
    result := VerInfo.szCSDVersion;
  except
  end;
end;

which returns something like: 'Service Pack 2'

Regards, Geo
Avatar of Wim ten Brink
Stomps everyone for suggesting to use the Windows API to get the Windows version information. That's just plain stupid...

In the unit SysUtils you'll see several variables:
  Win32Platform: Integer = 0;
  Win32MajorVersion: Integer = 0;
  Win32MinorVersion: Integer = 0;
  Win32BuildNumber: Integer = 0;
  Win32CSDVersion: string = '';

And yes, when SysUtils is used, they will be initialized with the proper values. So, please, PLEASE stop suggesting any API calls for information that is as easy to retrieve as just reading a variable.

Stomps a bit more and hopes you'll all learn from it. ;-)
You obviously do not know the arkana of version information.
Sometimes Windows lies like on Win 2000 if the program is named setup.exe.
ASKER CERTIFIED SOLUTION
Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
To get information about OS:

var
  info : OSVERSIONINFO;
begin
info.dwOSVersionInfoSize := sizeof(info);
GetVersionEx(info);
ShowMessage(
  format(
    'Major version: %d'#13#10+
    'Minor version: %d'#13#10+
    'Build number: %d'#13#10+
    'Platform Id: %d'#13#10+
    'CSD version: %d'#13#10,
    [
      info.dwMajorVersion,
      info.dwMinorVersion,
      info.dwBuildNumber,
      info.dwPlatformId,
      info.szCSDVersion
    ]
  )
);


dwPlatformId values:
VER_PLATFORM_WIN32s - Win32s on Windows 3.1.
VER_PLATFORM_WIN32_WINDOWS - Win32 on Windows 95 or Windows 98. For Windows 95, dwMinorVersion is zero. For Windows 98, dwMinorVersion is greater than zero.
VER_PLATFORM_WIN32_NT - Win32 on Windows NT®.
VER_PLATFORM_WIN32_CE - Win32 on Windows CE.

dwMajorVersion values:
4 - Windows 95
4 - Windows 98
4 - Windows Me
3 - Windows NT 3.51
4 - Windows NT 4.0
5 - Windows 2000
5 - Windows XP
5 - Windows Server 2003 family

dwMinorVersion values:
0 - Windows 95
10 - Windows 98
90 - Windows Me
51 - Windows NT 3.51
0 - Windows NT 4.0
0 - Windows 2000
1 - Windows XP
2 - Windows Server 2003 family



For more info search MSDN for GetVersionEx and OSVERSIONINFO.
replace
    'CSD version: %d'#13#10,
with
    'CSD version: %s'#13#10,
Path in registry (if you still need it):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
look at ProductName and CDSVersion
>> Stomps everyone for suggesting to use the Windows API to get the Windows version information. That's just plain stupid...

There are situations where you don't want to use SysUtils, since it adds quite a chunk of footprint to your binary file. This is true especially when building hook dlls, which should be as small as possible.
Madshi, it's also possible to read it from registry (using TRegistry).
I and Workshop_Alex even said the paths where to find that information.
Sure, but using an official API is IMHO better than reading the registry. Furthermore:

Little DLL: 13,5 kb
Little DLL using SysUtils.pas: 38,5 kb
Little DLL using Registry.pas: 85 kb
btw, Madshi, why do you want to use SysUtils here? Isn't GetVersionEx declared in windows.pas (not SysUtils.pas)? Same with OSVERSIONINFO type, used in my sample...
I didn't want to use SysUtils. That was Alex suggestion. For my small DLL I'd use Windows.pas and GetVersionEx. This way you can get along < 15kb.
Avatar of duke63

ASKER

think its still OK for me to read it out of the registry..

thanks to all!!!



@Madshi, you are right. Actually, I do write a lot of small applications too that don't use the SysUtils unit. But hey, you don't have to use SysUtils. You could just copy&Paste the function from SysUtils that fills these variables. :-)

But if you use the Registry unit then you automatically use the SysUtils unit too. SysUtils is even required if you use the default exception handlers from Delphi. (Although you could technically raise any object as if it's an exception object!)

The size of the final executable also depends on the Delphi version you're using, though. With Delphi 2 you get a very small result. With Delphi 7 the minimum size is around the 24 KB. But I'm also very aware that while it's a nice challenge to write very small binaries, with current disk and memory resources you could wonder why you would take all this trouble instead of using the faster development tricks in the default libraries. Especially the basic units like SysUtils, ActiveC, ShellAPI and maybe a few more an be quite useful at times.
For example, I wrote a small trayicon application that allows me to change my desktop image, even with Active Desktop enabled. It was a nice challenge and it became a 34 KB binary. Could it have been smaller? Well, perhaps it could but I needed several units because I needed to access COM objects for the Active Desktop stuff. (The source is available at http://workshop-alex.org/WallPaper/WallPaper.html if you're interested...) The time it would take me to reduce the size with about 15 KB would not be worth the trouble in this case, I assumed. It could be a little bit smaller, I guess. But the additional hassle of Initializing the COM system and copy&paste the code and GUID's and classes and interfaces that I would need would make this source a bit more complex. Without the ActiveDesktop support, it would not need any of the units except Windows, though. And thus it would be smaller. But it's just something I cannot avoid if I want to find a balance between development speed and final size.

Then again, if you only use the Windows unit with the Windows Registry API, you could read the version information with a very small executable... :-) Question is, would the rest of the code also keep it small?
To get smaller executable, you can also use some packers (UPX, for example)..
Usually I don't care about the exe too much. But when writing hook dlls it's a different situation. A hook dll is usually loaded into processes which are not aware of its existence. So in order to not impact stability the hook dll should be as small as possible and should not do anything but the absolutely necessary things. SysUtils has some stuff in its initialization section, so has Classes. So those are 2 units I'm usually avoiding to use for hook dlls. I've already heard about problems when Classes is used for hook dlls (rare problems, but problems nevertheless).
Well, hook DLL's would be one of the few exceptions then where it's important to keep things as small as possible. Of course you also have a problem with Delphi executables since even a small executabe will probably eat up about a megabyte of memory from the process for it's own internal stack. Thus you have 20 KB of code with 1000 KB of stack space. (But you're decreasing the stack size too, I assume?) :-)

Would there be any other examples of applications where SysUtils would actually be just in the way? If not, then I don't see any problems with it.
Nope, mainly hook dlls. (And I don't decrease the stack size.)
So, shouldn't you decrease the stack size in that case? Just to prevent the keyhook to eat up too much memory from the other process?

Oh, well... It is fun to try to make an application as small as possible. But the question is always if it's worth the trouble. With hook DLL's it often is but with other applications you will need to spend additional time on a project just to save a few bytes. Is it worth a few hours work just to decrease the final size with another 20 KB?
Decreasing stack size might result in stack overflows. So I'm usually not doing that. Better losing some resources than using stability.
duke63,
don't rely on that string (CSDVersion) in registry. Everyone can write there what he wants. On the other hand GetVersionEx can't be fooled that way. Just bear that in mind.

Workshop_Alex,
I've never said I'm smart.
Avatar of duke63

ASKER

geobul,

yes, it can be fooled! But for what reasons?  I will keep it in mind (hopefully ;-))
Executable size is not a problem for us.
We are reading and writing other registry values anyway.
So I think we can live with that and it works fine.

thanks,
duke63