othulke
Posts: 27
Joined: Thu Aug 01, 2013 1:51 pm

Default for InstallTypeDlg in mixed per-machine/user setup

Hi there,

I've just created a setup using AI 11.4.1 offering the user to choose whether installation will be done per-user or per-machine using the InstallTypeDlg (Installation Type on Install Parameters is set to "Per-machine if user is administrator, per-user otherwise). Almost everything works as expected.
However, when starting the setup on Windows 7 the "Install for everyone"-RadioButton is always preselected no matter what permissions the user has (AI_InstallPerUser is set to 0).

Is there any way to have AI_InstallPerUser default to 0 for Administrators only and to 1 for users without administrative permissions?

Furthermore the VerifyReadyDlg always shows the UAC icon. Even if per-user installation has been selected on the InstallTypeDlg. Shouldn't that only be shown when elevation is required for installation?

Any help on this subject is greatly appreciated!

Thanks in advance,
Oliver
Eusebiu
Posts: 4931
Joined: Wed Nov 14, 2012 2:04 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Oliver,
Is there any way to have AI_InstallPerUser default to 0 for Administrators only and to 1 for users without administrative permissions?
I'm afraid that starting with Windows Vista, there is no property that tells if the user is admin or not (because of the UAC security).

However, you can create your own custom action with this functionality and set the [AI_InstallPerUser] property to the appropriate value. Maybe the How to check if the current user is an Administrator (even if UAC is on) article can help you.
Furthermore the VerifyReadyDlg always shows the UAC icon. Even if per-user installation has been selected on the InstallTypeDlg. Shouldn't that only be shown when elevation is required for installation?
This may happen if you have some configuration in your project that requires admin rights. For example, you should not install files in a folder that requires admin rights (i.e. Program Files), you should not write registry entries under the HKLM hive, etc. Do not try make any action that requires elevation.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
othulke
Posts: 27
Joined: Thu Aug 01, 2013 1:51 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Eusebiu,

thanks to your help I was able to properly preselect the installation type most appropriate to the current user's permissions.

Unfortunately I couldn't find any reasons why the UAC shield is getting displayed when per-user installation is selected.
As far as I could see, there are no items in the MSI that would require elevation.
During per-user installation I don't even get the UAC prompt and the installation works fine.

Are there any logging entries I could look for to find the reason for the UAC shield being displayed?

Thanks in advance for your support!

Best regards,
Oliver
Eusebiu
Posts: 4931
Joined: Wed Nov 14, 2012 2:04 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Oliver,

I'm not sure why this happens. Can you please send us the .AIP (project file) and a verbose log of the installation to support at advancedinstaller dot com, so we can investigate them?

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
othulke
Posts: 27
Joined: Thu Aug 01, 2013 1:51 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Eusebiu,

I just sent you an email with logs and the AIP file.

Best regards,
Oliver
Eusebiu
Posts: 4931
Joined: Wed Nov 14, 2012 2:04 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Oliver,

I tested the resources that you sent and, indeed, I reproduced the problem. This seems to be an Advanced Installer issue. A fix will be available in a future version of Advanced Installer, thank you for bringing it to our attention.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Andrey
Posts: 47
Joined: Thu Jul 10, 2014 9:06 am

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Oliver, Eusebiu,
thanks to your help I was able to properly preselect the installation type most appropriate to the current user's permissions.
I've followed the your link but didn't find how to execute vb6 code in custom action.
Please tell me how can I initialize property with value returned from this code?

Code: Select all

Type OSVERSIONINFO
	dwOSVersionInfoSize As Long
	dwMajorVersion As Long
	dwMinorVersion As Long
	dwBuildNumber As Long
	dwPlatformId As Long
	szCSDVersion As String * 128
End Type

‘ dwPlatformId values
Public Const VER_PLATFORM_WIN32s = 0
Public Const VER_PLATFORM_WIN32_WINDOWS = 1
Public Const VER_PLATFORM_WIN32_NT = 2
Public Declare Function GetVersionEx Lib “kernel32? Alias “GetVersionExA” (ByRef lpVersionInformation As OSVERSIONINFO) As Long

‘ These functions are for getting the process token information, which IsUserAnAdministrator uses to
‘ handle detecting an administrator that’s running in a non-elevated process under UAC.
Private Const TOKEN_READ As Long = &H20008
Private Const TOKEN_ELEVATION_TYPE As Long = 18
Private Declare Function IsUserAnAdmin Lib “Shell32? Alias “#680? () As Integer
Private Declare Function CloseHandle Lib “kernel32? (ByVal hObject As Long) As Long
Private Declare Function OpenProcessToken Lib “advapi32.dll” (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function GetTokenInformation Lib “advapi32.dll” (ByVal TokenHandle As Long, ByVal TokenInformationClass As Long, TokenInformation As Any,_ ByVal TokenInformationLength As Long, ReturnLength As Long) As Long

Public Function IsUserAnAdministrator() As Boolean
	On Error GoTo IsUserAnAdministratorError
	IsUserAnAdministrator = False
	If IsUserAnAdmin() Then
		IsUserAnAdministrator = True
		Exit Function
	End If

	‘ If we’re on Vista onwards, check for UAC elevation token
	‘ as we may be an admin but we’re not elevated yet, so the
	‘ IsUserAnAdmin() function will return false
	Dim osVersion As OSVERSIONINFO
	osVersion.dwOSVersionInfoSize = Len(osVersion)
	If GetVersionEx(osVersion) = 0 Then
		Exit Function
	End If

	If osVersion.dwPlatformId <> VER_PLATFORM_WIN32_NT Or osVersion.dwMajorVersion < 6 Then
		‘ If the user is not on Vista or greater, then there’s no UAC, so don’t bother checking.
		Exit Function
	End If

	Dim result As Long
	Dim hProcessID As Long
	Dim hToken As Long
	Dim lReturnLength As Long
	Dim tokenElevationType As Long

	‘ We need to get the token for the current process
	hProcessID = GetCurrentProcess()
	If hProcessID <> 0 Then
		If OpenProcessToken(hProcessID, TOKEN_READ, hToken) = 1 Then
			result = GetTokenInformation(hToken, TOKEN_ELEVATION_TYPE, tokenElevationType, 4, lReturnLength)
			If result = 0 Then
				‘ Couldn’t get token information
				Exit Function
			End If
			If tokenElevationType <> 1 Then
				IsUserAnAdministrator = True
			End If
			CloseHandle hToken
		End If
		CloseHandle hProcessID
	End If
	Exit Function

	IsUserAnAdministratorError:
		‘ Handle errors
End Function
___
Best regards,
Andrey
Eusebiu
Posts: 4931
Joined: Wed Nov 14, 2012 2:04 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

Hi Andrey,

I'm not sure if a VB6 custom action can set MSI properties because I haven't worked with that. However, you can create a custom action as discussed on the Server install versus PC install - Appliation folder thread.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Andrey
Posts: 47
Joined: Thu Jul 10, 2014 9:06 am

Re: Default for InstallTypeDlg in mixed per-machine/user set

Thanks for link,
I have implemented C++ dll which modifies my property with MsiSetProperty winapi funcition. It works.

this may be useful to someone:
IsAdmin is set when user is in administrator group or MSI launched with eleveated rights, or launched at XP.

Code: Select all

#include <shlobj.h>
#include <VersionHelpers.h>
#include <windows.h>
#include <Msiquery.h>

namespace
{
const wchar_t *g_isadmin_property = L"IsAdmin";
const wchar_t *g_true_val = L"1";
const wchar_t *g_false_val = L"0";
} // namespace


UINT SetIsAdminProperty(bool is_admin, MSIHANDLE hInstall)
{
	const wchar_t *ret_value = is_admin ? g_true_val : g_false_val;
	return MsiSetProperty(hInstall, g_isadmin_property, ret_value); 
}

UINT __stdcall IsUserAdmin(MSIHANDLE hInstall)
{
	bool is_admin = false;
	if (IsWindowsVistaOrGreater())
	{	
	
		HANDLE process_id = GetCurrentProcess();
		if (process_id == NULL)
		{
			SetIsAdminProperty(false, hInstall);
			return 1;
		}

		HANDLE token_handle = NULL;
		if (!OpenProcessToken(process_id, TOKEN_READ, &token_handle))
		{
			SetIsAdminProperty(false, hInstall);
			return 1;
		}

		TOKEN_ELEVATION_TYPE tokenElevationType;
		DWORD bytesUsed = 0;
		if (!GetTokenInformation(token_handle, TokenElevationType, &tokenElevationType, sizeof(tokenElevationType), &bytesUsed))
		{
			SetIsAdminProperty(false, hInstall);
			return 1;
		}

		if (tokenElevationType != TokenElevationTypeLimited)
		{
			is_admin = TRUE == ::IsUserAnAdmin();
			return SetIsAdminProperty(is_admin, hInstall);;
		}

		TOKEN_LINKED_TOKEN linkedToken;
		if (!GetTokenInformation(token_handle, TokenLinkedToken, &linkedToken, sizeof(HANDLE), &bytesUsed))
		{
			SetIsAdminProperty(false, hInstall);
			return 1;
		}

		BYTE adminSID[SECURITY_MAX_SID_SIZE];
		DWORD sidSize = sizeof(adminSID);
		if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, 0, &adminSID, &sidSize))
		{
			SetIsAdminProperty(false, hInstall);
			return 1;
		}

		BOOL isMember = FALSE;
		if (!CheckTokenMembership(linkedToken.LinkedToken, &adminSID, &isMember))
		{
			SetIsAdminProperty(false, hInstall);
			return 1;
		}
		is_admin = (isMember != FALSE);
	}
	else
	{
		is_admin = TRUE == ::IsUserAnAdmin();
	}
	return SetIsAdminProperty(is_admin, hInstall);
}
__
Best regards,
Andrey
Last edited by Andrey on Fri Nov 07, 2014 6:43 am, edited 1 time in total.
Eusebiu
Posts: 4931
Joined: Wed Nov 14, 2012 2:04 pm

Re: Default for InstallTypeDlg in mixed per-machine/user set

I'm glad you got this working Andrey.

Thank you for sharing your solution with us, I'm sure it will help other users in the future.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Eusebiu
Posts: 4931
Joined: Wed Nov 14, 2012 2:04 pm

Re: Default for InstallTypeDlg in mixed per-machine/user setup

Hello,

The elevation shield issue was fixed in version 16.0 of Advanced Installer released on May 28th, 2019.

Best regards,
Eusebiu
Eusebiu Aria - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Building Installers”