Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Cleaning up a Win32 Application to work under Vista


So for the last few days I've been going through the final steps of updating Html Help Builder to properly run under Windows Vista without any file permissions, registry or other sort of elevation requirements. In theory the application should run fine after installation without any sort of crutch like Folder Virtualization.

Some may snicker and say - "What took you so long; Windows guidelines have been saying that for years". You know don't store data in Program Files, use a Documents folder for default data locations and AppData for 'application specific' data. And you'd be right <g>...

But then again Html Help Builder is a pretty old application that predates the strict Windows guidelines (I think those came about with Win2000 maybe NT 4.0) which really didn't get enforced seriously until XP (via policy) and now by default in Vista. So it took me a while to  be concerned about the issues. Underlying it all though is the fact that I really dislike the 'Scatter files all over the place mentality that ensues if you really follow the Windows guidelines: A folder for the user in Documents, 'Application configuration data' into a seperate AppData folder, Shared data yet somewhere else. Before you know it you have files scattered in 5 different locations. Messy if the application ever has to move...

But anyway it needed to be done and the process took much longer than I had planned. Html Help Builder is pretty well organized internally and pushing things into new directories is not really a big issue. But it turned out there were lots of little issues that I hadn't planned on at all. For example:

  • Local file generation for Html Previews
  • Local file generation for Compiled Scripts (if no project is yet open)
  • The Html Help Builder Auto-Update functionality
  • The 'global' configuration file for Html Help Builder

Testing this stuff  and trying to isolate file 'violations' can be tricky under Vista, because Vista - with UAC on - automatically has Folder Virtualization enabled. Folder Virtualization attempts to detect a non allowed file operation like a write operation in the install directory and automatically copies the file to a virtual folder (in your Documents/AppData store) and updates the file there.

Folder virtualization sounds like a nice workaround, but it has two problems: It seems that it really slows file operations down noticably and it can cause big problems if more than one user needs to use an application and share the data in in the install directory (I'll come back to this in a minute in regards to file updates).

So while testing your app for restricted rights you probably want to do one of two things to check for invalid file access:

  • Turn Folder Virtualization off
  • Leave Folder Virtualization on and check the virtualization store to see what got updated

While checking this stuff out you can turn Folder Virtualization off by typing Local Security Policy into the start menu and choose Local Policies, Security Options, then User Account Control: Virtualize File And Registry...:

Make sure to log off and log back on which is required before security policy changes are applied.

This allows you to run your app and have it blow up (or whatever it will do) whenever it tries to write local data. While checking out Html Help Builder I ran into a number of the small issues mentioned above, like writing configuration information and creating on the fly compiled code for a couple of odd man operations (usually this stuff happens in actual project locations which are in the Documents folder, but if no project is open <s>).

The other option is go ahead and leave Folder Virtualization enabled and go ahead and run your application. Test your application thouroughly or simply run it as you normally would for a few days. Then check out the virtual store and see what actually got updated there. The virtual store lives in your Users\<yourAccount> directory in AppData/VirtualStore/Program Files/<yourAppName>:

Unlike the picture above if you've cleaned up your app properly there shouldn't actually be a virtualization folder at all! If you do see files in this location it means there are still some parts of your application writing locally where they shouldn't!

Some things just won't work with Low Rights

Try as you might there might be some things that simply won't work in the low rights scenario. For example, in Html Help Builder I have an Auto-Update mode that downloads the latest version to a local location, then shuts down Html Help Builder, updates the downloaded files and then restarts Html Help Builder. There's no good way that I could think of to make this process work without requiring administrative rights - and maybe that's not such a bad thing because ultimately this is very viral behavior if it weren't for the prompts that occur and ask you whether you actually want to perform the update <s>...

So how do I get around this issue? Not very gracefully - I let the user know and prompt with a detailed error message.

Detailed enough for 'ya? This is a nuisance for sure but I think it's vital that the user is given enough information to proceed at this point so this dialog pops up explaining what options are available.

The code checks whether the user is an Administrator with the IsUserAnAdmin Win32 API call which correctly identifies the user's 'real' Administrator status in Vista. So even with Admin Approval mode enabled and running as a 'pseudo admin' user this function will return false and cause this dialog to be raised.

In case you're wondering - no that's not a standard Vista dialog but a custom dialog window I have in my library that uses a Web Browser control to generically display longer messages to the user along with the ability to add arbitrary buttons to the dialog. <s> It comes in very handy for displaying longer messages that would be overkill for a message box - the additional formatting that even simple HTML provides really helps (hey this is one thing nice in WPF - that sort of thing is native!).

COM and .NET Com Interop Registration

If the user chooses to update now and run As Administrator the update process works correctly by downloading the update into a temporary folder then launching the updater which inherits the Administrative Rights because it's a child process, and then then updates the original application and restarts.

There are a few other things that get similar treatment in Html Help Builder. For example, you can choose to re-register various components by re-registering the Html Help Builder COM component or the .NET Interop assembly used for importing .NET assemblies. Another scenario is where the user doesn't have the .NET runtimes installed at time of installation so COM Interop registration has no effect (no RegAsm available at install time) then later installs .NET (or a different version of .NET). Although .NET is now installed Html Help Builder does not have the COM Interop assembly registered. Internally Html Help Builder checks for registration and tries to register if it's not already registered. This also no longer works in Vista with UAC because COM registration requires Admin rights.

The same approach with the dialog is taken for this now, although it's not as flexible as before - previously you could just use a feature and Html Help Builder would check if installed and if not do it right then and there. Now an explicit step is required to make this happen.

 

So from an application perspective a lot of little changes like this were required, and while it all feels a lot more restrictive providing a less friendly user experience at the same time I also realize that these are not make or break issues and for the sake of security it's probably Ok to have to give them up.

Posted in FoxPro  Html Help Builder  Vista  

The Voices of Reason


 

Scott M
April 12, 2007

# re: Cleaning up a Win32 Application to work under Vista

Thanks Rick.

DuncanS
April 12, 2007

# re: Cleaning up a Win32 Application to work under Vista

Rick - you could use this to elevate the current app - use the "RUNAS" verb, which performs the elevation:

string[] commandLine = Environment.GetCommandLineArgs();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = commandLine[0];
startInfo.Verb = "RUNAS";
Process.Start(startInfo);

Rick Strahl
April 12, 2007

# re: Cleaning up a Win32 Application to work under Vista

Duncan GREAT TIP!!! The .NET code doesn't help me because this isn't a .NET application, but it does also work with ShellExecute which is great.

# DotNetSlackers: Cleaning up a Win32 Application to work under Vista


Rodney D
May 09, 2007

# re: Cleaning up a Win32 Application to work under Vista

Thanks for the heads up, I just ran into this yesterday and if it hadn't been for your blog I would have been highly agitated trying to figure out what in the world was going on.

Richard Norris
May 22, 2007

# re: Cleaning up a Win32 Application to work under Vista

I know this is an old blog but...

Could you allow the Administrator to store NT user details and use the LogonUser set of API's to do impersonation when required. I suppose the Shellexec is a much simpler method.

You could do this with your own prompt though (instead of storing) and try and use impersonation in this case. I'm not too sure about the complexity of the API and rights required on Vista though. Just thought it gives you a little more control over the situation.

Rick Strahl
May 23, 2007

# re: Cleaning up a Win32 Application to work under Vista

I wonder if this would even work - if you're running as a standard low user I don't think you can use the LogonUser APIs...

But event if it does - would you really trust an application to type in system user name and password? That's a pretty scary affair if you're typiing this into a black box app that you don't necessarily know what its doing.

If it did work though the more interesting thing might be to impersonate some built in account (like SYSTEM) which would give you full access... If anybody tries this I'd be curious to see whether that would work.

Overhead Garage Doors
April 01, 2008

# Overhead Garage Doors

I found something close in a forum. You might try there.
 

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2017