Forcing IE to run as IE9 with embedded web browser

If you embed IE in a windows application, you may notice that it runs in IE7 Emulated mode. This is likely NOT what you want.

I’ve added code like below to solve the problem:

string appName = ""; try { appName = Path.GetFileName(Assembly.GetEntryAssembly().Location);

const string IE_EMULATION = @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";

using (var fbeKey = Registry.CurrentUser.OpenSubKey(IE_EMULATION, true))

{ 

fbeKey.SetValue(appName, 9000, RegistryValueKind.DWord);

}
}

catch(Exception ex) { MessageBox.Show(appName + "\n" + ex.ToString(), "Unexpected error setting browser mode!"); }

There’s a special registry key that must be set before IE9 loads and is navigated … it must be set to the name of your application. Oddly, not the full path to your application, just the name of your executable.

You may want to delete this registry setting when your application exits.

WPF & System.Windows.Baml2006.TypeConverterMarkupExtension "The image format is unrecognized"

SNAGHTML4534e6a2If you recently added an icon to your WPF project (any .NET version, including .NET 3.5, and .NET 4.0) and it has support for an alpha channel (often referred to as the Vista icon format), stop. Why? Your WPF application won’t run on the latest service pack of XP as it’s not capable of decoding the format unfortunately. It’s a very frustrating error and a stupid "feature that Microsoft overlooked. I’ve hit this a few times unfortunately.

To fix, remove all of the alpha channel images from the ICO file and recompile.

Alternative to ApplicationSettings in .NET

After dealing with lost settings, an unclear upgrade path, and my own confusion surrounding the magic of Settings in a .NET client application, I decided to build my own.

You’re probably familiar with this UI in Visual Studio. It hasn’t changed much since it was first created:

image

A list of properties, data type, scope and a default value. Admittedly, it makes things simple. However, with my WPF .NET application that I created a few years ago (SnugUp), I’ve always been troubled by the magic of the settings. It was too easy to get in a situation where a user would loose their settings doing uninstalls, reinstalls, upgrades.

While I’m sure it’s possible to make the built in settings classes to work, it wasn’t worth the effort for me to understand them and learn what the nuances of where they’re placed, how to do a decent upgrade, how not to loose them, etc.

In the SnugUp WPF UI, the code uses a two-way bindings to directly edit the settings of the application (like: "{Binding AppSettings.DebugMode}"). It was simple, and all I needed. It’s handy that ApplicationSettingsBase implements the INotifyPropertyChanged interface which WPF needs for simple two-way data bindings.

My solution, which I admit is heavier than the original as it requires a large additional assembly is to use JSON.NET as the serializer/deserializer for a new settings class I created.

So, the basic pattern:

   1: public class ApplicationSettings : INotifyPropertyChanged

   2: {

   3:     public event PropertyChangedEventHandler PropertyChanged;

   4:  

   5:     private bool _debugMode;

   6:     private string _albumNameFormat;

   7:     private string _extraFileExtensions;

   8:     private bool _automaticRun;

   9:     private string _galleryCreationSubCategory;

  10:     private bool _filenameOnlyCheck;

Properties created the standard way for INotifyPropertyChaged:

   1: private DateTime _nextUpdateCheck;

   2: public DateTime NextUpdateCheck

   3: {

   4:     get { return _nextUpdateCheck; }

   5:     set

   6:     {

   7:         if (_nextUpdateCheck != value)

   8:         {

   9:             _nextUpdateCheck = value;

  10:             RaisePropertyChanged("NextUpdateCheck");

  11:         }

  12:     }

  13: }

I wanted a predictable path for storing settings (so it would be easy to document and backup for users). I used the AssemblyCompany attribute and the AssemblyProduct attribute as the folder names:

   1: internal static string GetSettingsDirectory()

   2: {

   3:     string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

   4:     var attrs = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);

   5:     if (attrs.Length == 1)

   6:     {

   7:         path = Path.Combine(path, ((AssemblyCompanyAttribute)attrs[0]).Company);

   8:  

   9:     }

  10:     attrs = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);

  11:     if (attrs.Length == 1)

  12:     {

  13:         path = Path.Combine(path, ((AssemblyProductAttribute)attrs[0]).Product);

  14:     }

  15:     return path;              

  16: }

In this WPF application, in the AssemblyInfo.cs file, the attributes are set as follows:

   1: [assembly: AssemblyCompany("WiredPrairie.us")]

   2: [assembly: AssemblyProduct("SnugUp")]

On my machine, that maps to this path:

d:\Users\Aaron\AppData\Roaming\WiredPrairie.us\SnugUp\

Loading settings then is straightforward using JSON.NET:

   1: public static ApplicationSettings Load(string filename)

   2: {

   3:     ApplicationSettings settings = null;

   4:     var directory = GetSettingsDirectory();

   5:     var path = Path.Combine(directory, filename);

   6:  

   7:     if (File.Exists(path))

   8:     {

   9:         string fileData = File.ReadAllText(path);

  10:         try

  11:         {

  12:             settings = JsonConvert.DeserializeObject<ApplicationSettings>(fileData, new JsonSerializerSettings { });

  13:         }

  14:         catch { }

  15:     }

  16:     if (settings == null)

  17:     {

  18:         settings = new ApplicationSettings();

  19:         SetDefaults(settings);

  20:         // initialize settings once

  21:         Save(settings, filename);

  22:     }

  23:     return settings;

  24: }

In my code, if the settings file didn’t exist or fails to serialize into something meaningful, a new settings file is created with a few defaults. (I haven’t decided what to do when there’s an exception when reading the file, hence the empty catch).

Saving the settings is just as easy:

   1: public static void Save(ApplicationSettings settings, string filename)

   2: {

   3:     Debug.Assert(settings != null);

   4:     var directory = GetSettingsDirectory();

   5:     var path = Path.Combine(directory, filename);

   6:  

   7:     JsonConvert.SerializeObject(settings);

   8:  

   9:     if (!Directory.Exists(directory))

  10:     {

  11:         Directory.CreateDirectory(directory);

  12:     }

  13:  

  14:     var fileData = JsonConvert.SerializeObject(settings, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate });

  15:     try

  16:     {

  17:         using (StreamWriter writer = File.CreateText(path))

  18:         {

  19:             writer.Write(fileData);

  20:             writer.Close();

  21:         }

  22:     }

  23:     catch { }

  24: }

The SerializeObject method returns a string which is then written to a file using a StreamWriter.

I added a Save method to the instance of the ApplicationSettings:

   1: public void Save()

   2: {

   3:     ApplicationSettings.Save(this);

   4: }

This preserved the functionality that exists in the built in Settings support in .NET (which was being used in my application).

By keeping all of the property names the same and making a few tweaks to the types of some fields in my application, I had swapped out the entire “settings” infrastructure in about 45 minutes.

I’m planning some other JSON activities within my application, so the overhead of using JSON.NET is acceptable.

The best part of this alternative is that there isn’t any magic. It’s all easy to manage. Further, I can easily modify my installer to properly handle/update, etc., the settings file with just a few clicks.

I’m not going back to the built-in .NET settings support again. I’ve learned my lesson.  Smile

What have you done for “user” settings?

Resource Intensive WPF Progress Bar (animation)

I’m using a progress bar in a small WPF application I’m working on and noticed that the Private Working Set for my application seemed higher than I expected.

My application, once simplified down to it’s most basic element, consisted of:

Window, Grid, ProgressBar

On my Windows 7 x64 machine, running the application uses around 29MB (private working set).

Removing the animation only from the visual template drops the private working set to 19MB.

So, it appears that the animation alone causes an extra 10MB of private working set to be needed. Sorry, but that’s crazy (especially for my application)!

If anyone has any specific theories – speak up! Here’s the basic starting Window I created:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="PerfProgressBar.Window1"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ProgressBar x:Name="progressBar1" Value="100" />
    </Grid>
</Window>

I’m not going to post the entire ProgressBar template, but if you want to reproduce the problem (and see how the animation impacts the memory requirements, just comment out the “Animation” rectangle in the control template (and in the trigger as well):

<Rectangle x:Name="Animation" Fill="{TemplateBinding Foreground}" Grid.ColumnSpan="3" Grid.RowSpan="2">
    <Rectangle.OpacityMask>
        <MultiBinding>
            <MultiBinding.Converter>
                <Microsoft_Windows_Themes:ProgressBarHighlightConverter/>
            </MultiBinding.Converter>
            <Binding Source="{StaticResource ProgressBarIndicatorAnimatedFill}"/>
            <Binding Path="ActualWidth" ElementName="Background"/>
            <Binding Path="ActualHeight" ElementName="Background"/>
        </MultiBinding>
    </Rectangle.OpacityMask>
</Rectangle>

<Trigger Property="IsIndeterminate" Value="false">
    <Setter Property="Fill" TargetName="Animation" Value="#80B5FFA9"/>
</Trigger>

Apparently, the ProgressBarHighlightConverter is intense (a little double checking in Reflector confirms!).

(All animations have some price of course – as an experiment I rotated the progressbar in a storyboard and that used about 7MB).

The moral of the story here really is to make sure you do some sanity checks against your [fill-in-the-blank] technology so that you understand how it uses system resources such as memory, CPU, etc, as it may have an impact on the success or failure of your application. I’ll leave out the gratuitous animations in my application so it doesn’t use memory unnecessarily.