Wyatt Says...
Posts Tagged ‘.net’
Shield icons, UAC, and process elevation in .NET on Windows 2000, XP, Vista, and 7
October 21st, 2009
Comment Now
One of the great things about Vista and Windows 7 is the user isolation. Even admin users need to “elevate” their account to make system changes. Take this Date and Time dialog from Windows 7 as an example:

Every user can view the Date and time, but only administrators can change it.
Adding this ability to your .NET application
Although this series of articles is called “7 days of Windows 7” this particular article is applicable to Windows 2000 – Windows 7.
Step 1. Do we have permission?
The first step is to check if we can write to system registry or system files & folders. There are many ways to do this, but the easiest method is a simple Windows API call:
// check if user is an admin for Windows 2000 and above
[DllImport("shell32.dll", EntryPoint = "#680", CharSet = CharSet.Unicode)]
public static extern bool IsUserAnAdmin();
This will return false if you’re a limited user on Windows 2000 – Windows 7, and will also return false if you are an admin but aren’t elevated on Windows Vista and Windows 7.
In other words, it will return false if you don’t have permission to access system files & registry. And ‘ IsUserAnAdmin” returns true if you do have permission.
Step 2. Notifying the user that elevation will happen: UAC Shield Icon
To set the shield icon to one of your buttons you have to do a few things. First, set the FlatStyle of your button to “System”:

Next, you need to define a couple of functions:
public static bool AtLeastVista()
{
return (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6);
}
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(HandleRef hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
public static void SetButtonShield(Button btn, bool showShield)
{
//Note: make sure the button FlatStyle = FlatStyle.System
// BCM_SETSHIELD = 0x0000160C
SendMessage(new HandleRef(btn, btn.Handle), 0x160C, IntPtr.Zero, showShield ? new IntPtr(1) : IntPtr.Zero);
}
Now, simply use this snippet in your code:
…
// UAC Shield on next button for Windows Vista+
if (AtLeastVista())
SetButtonShield(btnName, true);
…
Step 3. Re-launching process with administrator privileges
All we have to do now is show the elevation dialog and elevate the current program. You might want to specify some arguments, but the barebones of it is as follows:
ProcessStartInfo psi = new ProcessStartInfo
{
Arguments = "-justelevated",
ErrorDialog = true,
// Handle is the handle for your form
ErrorDialogParentHandle = Handle,
FileName = Application.ExecutablePath,
Verb = "runas"
};
try
{
Process.Start(psi);
Close();
}
catch (Exception ex)
{
// the process couldn't be started. This happens for 1 of 3 reasons:
// 1. The user cancelled the UAC box
// 2. The limited user tried to elevate to an Admin that has a blank password
// 3. The limited user tries to elevate as a Guest account
MessageBox.Show(ex.Message);
}
Step 4. Code signing
Chances are that if you try to elevate your application you’ll get an ugly yellow elevation box:


To get the nice UAC box you’ll need to code sign your application. I won’t link to any code signing providers (because the list is huge), but you can get a code signing certificate from anywhere between $100 for 3 years to $400 or $500 for a single year. It depends on the company you use and the amount of searching you want to do.
7 Days of Windows 7
Join me tomorrow when I talk about Every possible Windows Vista and Windows 7 .NET Control You could ever want. See the full list of articles in the series.
You’re dying to know what the AIC is, aren’t you? No, it’s not a test to see if you qualify for insurance with a talking wallaby. Rather, you’ll be glad to hear that I’ve coined a new computer acronym which you can add to your arsenal of entirely forgettable “stupid geek talk.”
AIC Test: Anger Induced Clickscapade Test
The AIC test (pronounced “ache test”), briefly, is a confirmation that your program works at 3a.m. Specifically it’s a guard that you, the programmer, put in place for your customers’ all-nighters. He’ll be running Firefox with over 30 tabs open, Photoshop with nearly a gig’s worth of images in memory, and several other CPU & memory intensive programs, plus your own program.
He’s 20 minutes away from finishing after nearly 20 hours of caffeine fueled work. He clicks a link in Firefox and the browser freezes. Realizing a bad situation in the making, he flips back to Photoshop to save his work. “Application Not Responding,” Windows gleefully reports. He switches from program to program, leaving a trail of unresponsive programs.
By the time he flips to your program, his Tea is in a puddle on his desk and he’s used phrases that would make a longshoreman blush. Now begins the anger induced clickscapade. Clicking furiously, and largely at random, he’s going to try to save his work, export and upload his data, and print a copy of his work all while your program blinks between responsive and unresponsive states. Your program has to process each click and keystroke perfectly. This means no flaky behavior.
How to run the test
From that series of events alone, the AIC test sounds suspiciously arbitrary. If you’ve taken even a beginners computer course you’ll already know that nothing in the computer is arbitrary or unpredictable. To illustrate my point I’ll describe the steps I took to fix an already usable SplitButton control to an AIC passable SplitButton control.
A little background
SplitButtons are everywhere from Firefox to Photoshop to many Microsoft products. Here’s a SplitButton in Firefox:

As the name SplitButton implies, the functionality of the back button in Firefox is divided. Click the near the green arrow and the browser goes back a page; click the downward pointing black arrow (the drop-down region) and a list of recently visited sites appears.
These types of buttons are seen so often in Windows programs, you’d think Microsoft would have built the functionality into the Windows API prior to adding it to Windows Vista. Not so. After googling for a few hours I found three options:
- A bloated commercial component suite. Only $280; who could refuse?
- A buggy, but open source SplitButton designed by some anonymous guy. Pass.
- A functioning, open source, SplitButton control written by a Microsoft programmer. Sounds perfect.
The tests, the subtleties
The SplitButton I opted to use was by the Microsoft programmer, Jessica. After an hour of use I noticed a few sticky parts in her nearly perfect implementation. First of all, the drop-down region of the SplitButton didn’t fill the full height of the button:
![]()
If the user clicks the right hand side of Jessica’s button the user will expect a menu to pop-up. However, the highlight shows that if the user clicks either the top or bottom five pixels they will have triggered the normal button click-event. At 3a.m. this subtlety is death. It’s an easy fix, so why not fix it?
Then there’s the matter of right clicking. In Firefox’s SplitButtons a right click shows the menu directly under the button – acting identical to clicking the drop-down region. Jessica’s implementation, along with SplitButtons in Windows toolbars, shows the menu wherever the right click happened. I prefer displaying the menu directly under the button so it doesn’t obscure the button’s text:

And lastly, Jessica forgot to implement the disabled state for the SplitButton. It’s another easy fix, and is essential if you disable buttons:
![]()
Why do I care? Why should you?
All of these “major” fixes took less than an hour to implement and test, and they reduced my own frustration with the button. I use the SplitButton in the InstantUpdate Designer so the user can select options when uploading their newly created update files:

If I were to use an unaltered version Jessica’s SplitButton, then a user could easily start large uploads when he only wanted to change an upload option. Quirks like these make months of hard work seem wasted. And, it’s only through anger induced clickscapades do these problems show themselves.
Update October 13, 2008: You can view all the latest changes at the SplitButton changelog page.
Download the fixed SplitButton. Open source, and confirmed working with .NET 2.0 and above (C#, VB.NET, etc.).
CueSharp v0.4.6 corrects a minor issue with the end lines on Unix machines vs. Windows machines. I’ve opted to change ‘\r\n’ (the windows type endline) to the more general C# function ‘Environment.NewLine.’ This will allow for correct output whether you’re using CueSharp with Mono on Linux or the vanilla .NET framework on Windows.
In other news, the site has undergone some minor performance and graphical tweaks in preparation for the (long-delayed) forum. If all goes to plans, the forum will be up this weekend (Feb. 24-25).
Lastly, my Water World article drew some interesting responses from people. Mostly negative, in fact. I wonder if these people realized that it wasn’t an exposition on the cons of water conservation, but rather a damnation of a misguided fool. Probably not. These people likely also think the caricature I painted of myself is reality, and not lifted straight from the pages of Charles Dickens. Patrick Stewart would be disappointed.
Subscribe to the RSS feed
Or subscribe by email