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

14 Responses to “WPF (Avalon) ClickOnce Application and FileOpenDialog”

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

    […] Here is  an attempt to explain why things work the way they are described in the last article about FileOpenDialog. There are two things we did to make this work on Vista and XP. […]

  2. gamekid Says:

    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.

  3. Jeff Braun Says:

    Things are much easier in VS2008 (maybe 2005?). I have XPsp2 on my box with .NET 3.0 and 3.5. My OpenFileDialog was having the same issues described above. So I cobbled together some pieces and came up with what worked for me.

    In my WPF application, I added to my project a new file of type “Application Manifest File” with a name of “app.manifest”. File Properties were:
    Build Action = None
    Copy to Ouput Directory – Do not copy
    Custom Tool –
    Custom Tool Namespace –
    File Name – app.manifest

    I edited the file adding this xml:

    I recompiled my app and whammo, updated OpenFileDialog with real XP look-n-feel.

    Jeff

  4. Jeff Braun Says:

    I guess it didn’t like my embedded xml code, so here:
    [dependency]
    [dependentAssembly]
    [assemblyIdentity
    type=”win32″
    name=”Microsoft.Windows.Common-Controls”
    version=”6.0.0.0″
    processorArchitecture=”X86″
    publicKeyToken=”6595b64144ccf1df”
    language=”*”
    /]
    [/dependentAssembly]
    [/dependency]

    replacing [ with >

  5. Random T. Says:

    This is very hot info. I think I’ll share it on Facebook.

  6. Justin Says:

    This only works for me if ClickOnce Security (and thus ClickOnce publishing) is NOT enabled. If ClickOnce is enabled, I get a File Not Found Microsoft.Windows.Common-Controls…. error on build. Do you know a solution?

  7. Keith Patrick Says:

    FYI on the Add New Item|Application Manifest File in VS2008: this option is apparently only available to C#…VB inexplicably doesn’t list it as a valid file type for its projects.

  8. Lelpeffow Says:

    Looks like you are a true pro. Did you study about the theme? hrhr

  9. ClickOnce, TaskDialogs, Common Controls and WPF Applications - Mike Taulty's Blog - Mike Taulty's Blog Says:

    […] blocked by this error message. I tried lots of ways to work around it but ended up being pointed to this post which talks you through how to work around this […]

  10. Alberta Calhoun Says:

    I and also my friends were found to be checking out the excellent tricks located on the blog and then quickly developed a terrible feeling I never thanked the website owner for them. My ladies are already consequently joyful to learn all of them and have in effect extremely been using these things. Appreciate your simply being well kind and for making a choice on certain high-quality issues millions of individuals are really desperate to know about. My personal sincere regret for not expressing gratitude to you sooner.

  11. Rod Viejo Says:

    I needed to write you the tiny word to finally say thanks again about the beautiful solutions you’ve shared on this site. It was simply tremendously generous with people like you to make publicly all many people could have distributed for an e book to get some bucks for their own end, mostly considering that you could have done it in the event you considered necessary. The strategies in addition served to become fantastic way to be sure that someone else have the identical desire the same as my own to learn whole lot more with reference to this issue. I’m sure there are lots of more fun opportunities ahead for individuals that check out your blog.

  12. http://tinyurl.com/fblepybus40514 Says:

    Thank you so much for spending some time in order to
    post “WPF (Avalon) ClickOnce Application and FileOpenDialog Desperately Seeking Love of
    Sophie”. Many thanks yet again -Bailey

  13. Norberto Says:

    Your personal article, “WPF (Avalon) ClickOnce Application and FileOpenDialog
    | Desperately Seeking Love of Sophie” cityofgreenwoodmn was in fact truly
    worth writing a comment here! Simply wanted to mention u really did a terrific job.
    Thanks for your time ,Chris


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

%d bloggers like this: