UAC and the shield icon << Back



In VDF 18.0, a new property "pbShield" was introduced to the "Button" control to allow you to add a little shield icon to your button to indicate that the action requires administrative rights (such as modifying things in HKEY_CLASSES_ROOT in the registry) to perform. Of course, if you are already running as an administrator, the shield icon shouldn't show up. If you are running pre-VDF 18.0, you can use the Windows message BCM_SETSHIELD (example below). Let's say you display the shield icon on a button, and the user clicks on it, then what? We can take a cue from Task Manager or Process Explorer. Both of them will relaunch itself to run as an Administrator (You are going to get the UAC prompt). The following example will do exactly that.

Use Windows
Use MapiDllCalls.pkg
Use cWorkspace.pkg

Define BCM_SETSHIELD For |CI$160C

Function ExePath Global Returns String
	String sExePath
	Integer iVoid
	ZeroString MAX_PATH to sExePath
	Move (GetModuleFileName(0, AddressOf(sExePath), MAX_PATH)) To iVoid
	Function_Return (CString(sExePath))
End_Function // ExePath

Function RemoveFileName Global String sFileName Returns String
	Integer iVoid
	Move sFileName to sFileName //Workaround the bug where byRef String get modified
	Move (PathRemoveFileSpec(AddressOf(sFileName))) to iVoid
	Function_Return (CString(sFileName))
End_Function // RemoveFileName

Procedure RelaunchAsAdministrator
	String sExe sDir
	Handle hInstance
	Move (ExePath()) to sExe
	Move (RemoveFileName(sExe)) to sDir
	Move (ShellExecute(0,"runas",sExe,"",sDir,SW_SHOW)) to hInstance
	If (hInstance<=32) Send Stop_Box "Unable to run as Administrator."
	Else Abort
End_Procedure // RelaunchAsAdministrator

Object oPanel is a ModalPanel
	Set Size to 100 100
	Object oButton is a Button
		Set Label to "Admin Mode"
		Set Size to 15 80
		Procedure OnClick
			If (IsAdministrator()) Send Info_Box "Do something that only Administrators can do"
			Else Send RelaunchAsAdministrator
		End_Procedure
		Procedure Page_Object Integer iPage
			Forward Send Page_Object iPage
			#IF !@>=180
			If (IsAdministrator()) Set pbShield to True
			#ELSE
			Move (SendMessage(Form_Window_Handle(Self,0), BCM_SETSHIELD, 0, Not(IsAdministrator()))) to iPage
			#ENDIF
		End_Procedure // Page_Object
	End_Object // oButton
End_Object // oPanel
Send Popup of oPanel
Free Web Hosting