Professional, Software

WPF (Avalon) ClickOnce Application and FileOpenDialog

One the main reasons why WPF (Avalon) provided its own OpenFileDialog is to provide access to file opening functionality in Internet zone security sandbox. This is done through SafeFileName and SafeFileNames properties. These properties can be used by applications running in security sandbox to provide functionality such as file uploads. These properties essentially dont allow applications running in sandbox access to full path of the file.

These class is wrapper on Windows Shell File Open dialog. This dialog is implemented in ComCtl32.dll. By default, application will use old version of ComCtl.dll and dialog will look different than XP themed dialog. Here are two different dialogs and I have marked the differences between two dialogs as my non-designers eyes can see.

When you run a Avalon application that uses OpenFileDialog class it does not bind against the version 6.0 of the ComCtl32.dll. You can get your application to bind against that particular version by embedding a manifest that specfies the version of the ComCtl32.dll that applications wants to use.

So this post is about two things…

  1. How to get WPF (Avalon) exe to load the right version of ComCtl32.dll so that you get right themed file open dialog on XP as well as Vista.
  2. How to get WPF (Avalon) ClickOnce applications to load the right version of ComCtl32.dll.

To get to there we will start with simple Application that invokes the OpenFileDialog.

Application Invoking FileOpenDialog

This is piece of cake but I listed it down here for completion sake. Also it is relevent to know that to get the right theme you dont need to change the actual code in the application.

Window1.Xaml

<Window x:Class=”FileOpen.Window1″
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Title=”FileOpen” Height=”300″ Width=”300″>
<StackPanel>
<Button Height=”45″ Margin=”77,70,85,0″ Name=”button1″ VerticalAlignment=”Top” Click=”OnClick”>File Open</Button>
</StackPanel>
</Window>

Window1.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;

namespace FileOpen
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>

          public partial class Window1 : System.Windows.Window
         { 
                     public Window1()
                    {
                            InitializeComponent();
                     }

                     void OnClick(object sender, RoutedEventArgs e)
                      {
                             Microsoft.Win32.OpenFileDialog fOpen = new  Microsoft.Win32.OpenFileDialog();
                             fOpen.ShowDialog();
                       }
         }
}

Compiling this application will get you top dialog in the above picture. It will not have right theme.

EXE to get XP/Vista Themed File Open Dialog

This is pretty straightforward and it is been documented.

  1. Create  a file named embed.manifest (you can name it anything) and paste following xml in it. Parts in red are the things that you will need to change to fit your application. version number is not the assembly version but the file version that you get by right clicking on EXE in explorer and go to properties of that file.
  2. It looks like this<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
    <assembly xmlns=”urn:schemas-microsoft-com:asm.v1″
    manifestVersion=”1.0″>
    <assemblyIdentity
    version=”1.0.2439.38563
    processorArchitecture=”msil”
    name=”FileOpen.exe
    type=”win32″
    />
    <description>Description of Application</description>
    <dependency>
    <dependentAssembly>
    <assemblyIdentity
    type=”win32″
    name=”Microsoft.Windows.Common-Controls”
    version=”6.0.0.0″
    processorArchitecture=”X86″
    publicKeyToken=”6595b64144ccf1df”
    language=”*”
    />
    </dependentAssembly>
    </dependency>
    </assembly>
  3. Start Visual studio and Open exe of your application
  4. you will see resources view. Right click to add Resources
  5. Click On Import and browse to the file that you created in Step1
  6. Set the resource type to “RT_MANIFEST”
  7. Change the ID from 101 to 1
  8. Save the file and close

When you run this EXE, you get the second dialog in the above picture with correct theme.

WPF (Avalon) ClickOnce Application to Get Right Themed Dialog

Generating the ClickOnce application is very easy. I will not go into detail here. But since VS generates the binary, application manifest and deployment manifest.  WPF supports two types of ClickOnce applications. Browser hosted Applications (XBap) and Windows based Application (.application). Xbap run in a hosting process called Presentationhost.exe. Since Presentationhost.exe already specifies something like above in its manifest, Xbaps running in presentationhost.exe process automatically get the right theme for the OpenFileDialog .

Window Based Application is where it gets interesting. Since these applications run in their own process. Each EXE needs to have above manifest embedded in them. Since generated manifest contains hashes of binaires and manifests, you can not change the EXE without updating the manifest that describe the application deployment. Tool called mage helps here where you can just update the manifest with new EXE and resign them. Do the same with deployment manifest. Sounds so simple so far…

But, it did not work. When I tried to regenerate manifests (Application as well as Deployment), deployment failed. Hence this post 🙂

So here is what you need to do….

Manifest that you will embed in this case will be little different from what you see in step 2 above. It will not have AssemblyIdentity element. It will just have reference to Common Controls dll.

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1″
manifestVersion=”1.0″>
<description>Description of Application</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type=”win32″
name=”Microsoft.Windows.Common-Controls”
version=”6.0.0.0″
processorArchitecture=”X86″
publicKeyToken=”6595b64144ccf1df”
language=”*”
/>
</dependentAssembly>
</dependency>
</assembly>

Embed this manifest in the same way as above.

Now if you regenerate application and deployment manifests using mage. It works !!. It works great on Vista!! lets open the champagene  

……………………………………….

Wait a second but deployment still fails on XP!!

Tweak to make it work on XP  too is

Open the Application manifest (FileOpen.exe.manifest in this case).

Change following line…

<asmv1:assemblyIdentity name=”FileOpen.exe” version=”1.0.0.0″ publicKeyToken=”855aa50c7de35a70″ language=”neutral” processorArchitecture=”msil” type=”win32″ />

to (Change in red bold)

<asmv1:assemblyIdentity name=”FileOpen.package” version=”1.0.0.0″ publicKeyToken=”855aa50c7de35a70″ language=”neutral” processorArchitecture=”msil” type=”win32″ />

Now you can again use MAGE to resign the application manifest and Deployment manifest. Now tihs works on XP as well as Vista with right themes for your OpenFileDialog.

Advertisements
Standard

2 thoughts on “WPF (Avalon) ClickOnce Application and FileOpenDialog

  1. Pingback: Little Big of Explaination « Breakpoint Inside Recursive Mind

  2. I quickly got so used to “Application.EnableVisualStyles” in Windows Forms that I forgot about the manifest method of enabling the styles in general Windows apps.

    As someone who likes WPF, I’ll never forget now.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s