e martë, 12 qershor 2007

How to Display the UAC Shield Icon inside .NET

Overview

When deploying enterprise applications and desktop systems, information technology (IT) administrators are often presented with the challenge of maintaining computer security while still enabling business productivity (usability) – traditionally two opposing forces. If systems and users were deployed in highly secure locked-down states, productivity would typically suffer because applications would cease to function properly in the absence of administrative privileges. In the other direction, if administrators opted for higher usability by granting end-users administrative privileges, systems became highly exposed to the effects of malware that could perform malicious actions such as stealing personal information and making unauthorized system changes. To make matters worse, IT administrators really didn’t have an easy way to balance the two requirements and often resorted to a one-or-the-other approach.

Enter the Microsoft Windows User Account Control (UAC) feature in Microsoft Windows Vista . With UAC IT administrators can easily deploy applications and service components with limited privileges (security) while still maintaining the ability to perform elevated tasks (usability) whenever needed.
More information about the features and benefits of UAC can be found at
http://technet.microsoft.com/en-us/windowsvista/aa906021.aspx.

One of the most visible features with UAC is the introduction of “elevated shield icon” decorated buttons that help users to identify actions and applications that require elevation. Take for example the task of changing the local system time on a Microsoft Windows Vista system which requires administrative privileges. Microsoft Windows Vista now indicates this requirement by displaying an elevated shield icon-decorated button in the date and time adjustment dialog.



This article shows how .NET developers can enable the same visual cues in their own Microsoft Windows Vista forms-based applications.

Decorating Windows Application Form Buttons with the Elevated Shield Icon in .NET


In unmanaged code (C/C++), there are several way that you could decorate a button with the elevated shield icon. The first method is to use the Button_SetElevationRequiredState macro and the second method is to send the BCM_SETSHIELD message to the target button control handle. If you take a look under the hood and install the Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Components, inside the file CommCtrl.h at line 7900 you’ll find the follow declaration for the Button_SetElevationRequiredState macro:

#define Button_SetElevationRequiredState(hwnd, fRequired) (LRESULT)SNDMSG((hwnd), BCM_SETSHIELD, 0, (LPARAM)fRequired)

As we can see, the Button_SetElevationRequiredState macro really just calls user32.dll!SendMessage with the BCM_SETSHIELD message. So in the coming example we’ll decorate a button control with an elevated shield icon from within managed code (specifically C#) using only the BCM_SETSHIELD message method. A link to the sample code is provided at the end of this article.



BCM_SETSHIELD Message MethodExposing the nuts and bolts behind the Button_SetElevationRequiredState macro gives us some useful information about how to use the BCM_SETSHIELD method successfully. A couple things need to happen before we can successful decorate our example button:
  • The target button control’s handle must be passed as the 1st argument to user32.dll!SendMessage.

  • The correct BCM_SETSHIELD value must be passed as the 2nd argument to user32.dll!SendMessage.

  • The value 0 must be passed as the 3rd argument to user32.dll!SendMessage.

  • A pointer to a Boolean true value must be passed as the 4th argument to user32.dll!SendMessage.

  • The target button control’s .FlatStyle member needs to be set to the system style.

  • The function user32.dll!SendMessage must be called from within our C# code.

Sounds like a colossal pain to implement, but it’s really not. Click here to see the code that does the above.


Now to decorate our example button control, we simply need to pass button control as the argument and our handy little EnableElevateIcon_BCM_SETSHIELD method takes care of the rest:



Conclusion

In this article we looked at how we could use the BCM_SETSHIELD message along with .NET P/Invokes to programmatically decorate Windows Vista forms application buttons with elevated shield icons.

While visual cues are helpful, developing applications to be UAC compliant however involves much more than just decorating buttons – there’s considerations such as file system virtualization, registry virtualization, over-the-shoulder (OTS) credentials, proper elevation methods and application manifests that developers need to consider. To learn more about these UAC aspects, please refer to the additional resources and references section.


Downloads

Additional Resources/References


2 comments:

Anonymous said...

I see that showing the UAC shield icon on a button works in VS 2005 (.NET 2.0), but I can't get it to show up in my VS 2003 apps that are using .NET 1.1. Is this possible?

Kevin Lam (Impacta LLC) said...

You should be able to do so in .NET 1.1 I believe. All you're doing is call SendMessage with a specified message value to a given control which should work ok in 1.1.

Are you trying to mark a button with the UAC shield? If so, then it's .FlatStyle property needs to be set to FlatStyle.System. Do you have that set?



--Kevin