views:

483

answers:

3

My setup should behave slightly differently when the program is installed on a Terminal Server. I know about GetSystemMetrics(SM_REMOTESESSION) but as far as I understood that will only tell me whether I'm running inside a RDP session. It would not catch the case where the server admin is logged on locally to install software, or would it?

Checking for the Terminal Server service does not appear to be viable either as that also runs on workstations when Remote Desktop has been enabled. I need to differentiate this from a true TS that allows multiple concurrent logon sessions.

Isn't there any other service or registry key that I check for?

+3  A: 

This is exactly what you need:

Detecting Whether Terminal Services Is Installed

Note that in addition to this you can use the value of GetVersion() to determine if you are at all running NT. If not NT then bail out.

// Are we running Windows NT?
DWORD dwVersion = GetVersion();
if (!(dwVersion & 0x80000000)) {
    // Is it Windows 2000 or greater?
    if (LOBYTE(LOWORD(dwVersion)) > 4) {
        // Check with VerSetConditionMask() and VerifyVersionInfo()
        return ..;
    }
    else  {
        // Windows NT 4.0 or earlier. Check ProductSuite value in
        // HKLM\\System\\CurrentControlSet\\Control\\ProductOptions
        return ..;
    }
}

return false;

The link shows the code you need to query if the version is Win2k or later

Magnus Skog
Thanks! That link pointed me in the right direction. But as the question was specifically aimed at doing this from within an InnoSetup script rather than in C++ I posted my solution as a separate answer.
Oliver Giesen
+1  A: 

I'm guessing that this question has a potential for many answers, all of which will seem slightly unsatisfactory.

For instance, what are the possible scenarios:

  • Workstation, with RDP enabled (ie. XP with remote help enabled)
  • Server, with RDP enabled (easily distinguishable from a workstation by checking the OS type)

However, what about a server that has the RDP option enabled, but it isn't used? How about a server that has the RDP option enabled, but the administrator is installing your software at the console, at a time of day when nobody is logged in through RDP? You wouldn't be able to determine if the server is actually in use, RDP-wise, or not.

The best way to give you a concrete answer is to ask why you need to determine this? What kind of functionality will you enable or disable if you were able to reliably detect this?

Lasse V. Karlsen
The reason is that the app in question is an Outlook addin and that we use floating licenses, i.e. every started instance of Outlook would usually use up a license. However, some customer buy fewer licenses than they have total users on the server. When installing on TS we therefore offer the additional option to install the app in deactivated state so that only those users for whom a license exists can enable the addin. I want to hide this option for installations on non-TS as it would be confusing to users there.
Oliver Giesen
+1  A: 

Thanks to the link provided by Magnus Skog I discovered that InnoSetup already supports the GetWindowsVersionEx API function. Therefore all I had to do was this:

function IsRunningOnTS: Boolean;
var
  lWinVer: TWindowsVersion;
begin
  GetWindowsVersionEx(lWinVer);
  Result := (lWinVer.SuiteMask and VER_SUITE_TERMINAL) <> 0;
end;

I have successfully tested this for the following scenarios:

  • logged on locally to an XP workstation with RDP enabled (returns False)
  • logged on remotely to a Terminal Server via RDP (returns True)
  • logged on remotely to a workstation via RDP (returns False)

I did not yet have the opportunity to test while logged on locally on a TS. Will update this post when I have.

Oliver Giesen