The scenario is that an Image that has its Stretch property set to None still has a different size from the original image source. You check the Padding, the Margin, the VerticalAlignment and HorizontalAlignment properties, you play with the RenderOptions and SnapsToDevicePixels and nothing seems to work. You specify the Width and Height manually and the image is clipped. The problem here, believe it or not, is that the DPI setting of the image source is different from the system DPI setting.

The solution is an ugly thing:

<Image
Stretch="Fill"
Width="{Binding RelativeSource={RelativeSource Self}, Path=Source.PixelWidth}"
Height="{Binding RelativeSource={RelativeSource Self}, Path=Source.PixelHeight}"/>
So set the Stretch to Fill so that it doesn't fill!

Here is the discussion where I got the solution from: How do I keep an image from being stretched when Stretch="None" doesn't work?.

The scenario is easy enough to create: make a Brush, use a Binding as the Color property, use your brush in your app, then start the application and change the system theme. An error "This freezable can not be frozen" will be triggered. The solution is to set x:Shared="False" for the brushes with color bindings.

An entire Microsoft Connect page is devoted to this issue, so get all the details there: Changing system theme throws "This freezable can not be frozen" exception

Update February 2016: The Microsoft Connect page has disappeared. Maybe it was because the bug was marked as "closed - by design", or some other Microsoft site revamp idiocy.

I had this control where a button was displaying a ContextMenu. I wanted to keep the ContextMenu open so I can manipulate its content. I had assumed that the StaysOpen property would do that for me; it did not. Also, I tried using a ContextMenuClosing event approach, only to discover that it is one of those rare "ing" events that doesn't have a Cancel property. I've looked in the sources of ContextMenu and Popup to see just what is going on and I have decided that the design was impossible to patch in order to get the behaviour I wanted.

In the end, the only solution I could find was to inherit from ContextMenu into a new class that would coerce the IsOpen property to true when StaysOpen is set to true. That did the trick. Here is the code:

public class StaysOpenContextMenu:ContextMenu
{
static StaysOpenContextMenu()
{
fixContextMenuStaysOpen();
}

private static void fixContextMenuStaysOpen()
{
IsOpenProperty.OverrideMetadata(
typeof(StaysOpenContextMenu),
new FrameworkPropertyMetadata(false, null,coerceIsOpen));
StaysOpenProperty.OverrideMetadata(
typeof(StaysOpenContextMenu),
new FrameworkPropertyMetadata(false, null, coerceStaysOpen));
}

private static object coerceStaysOpen(DependencyObject d, object basevalue)
{
d.CoerceValue(IsOpenProperty);
return basevalue;
}

private static object coerceIsOpen(DependencyObject d, object basevalue)
{
ContextMenu menu = (ContextMenu)d;
if (menu.StaysOpen)
{
return true;
}
return basevalue;
}

}


Hope it helps people out.

Update:

This solution only works for the body of the ContextMenu, the submenus are something else. However, the submenus are defined in the control template of a menu item, so that can be easily remedied by changing it to your needs. One quick and dirty solution would be to add a trigger that sets the IsSubMenuOpen property to true whenever StaysOpenOnClick is set. Or, if you simply want to freeze a menu in place, change the template so that the mouse click or hover will only trigger IsSubMenuOpen when the parent ContextMenu has StaysOpen to false, while the StaysOpen property of the MenuItem Popup is set to the ContextMenu StaysOpen.

I was working on this application and so I found it easy to create some controls as UserControl classes. However, I realised that if I wish to centralize the styling of the application or even move some of the controls in their own control library with a Themes folder, I would need to transform them into Control classes.

I found that there are two major problems that must be overcome:

  1. the named controls in a user control can be accessed as fields in the code behind; a theme style does not allow such direct access to the elements in the control template.
  2. the controls that expose an event may not expose an associated command. In a user control a simple code behind handler method can be attached to a child control event, but in a theme a command must be available in order to be bound.



Granted, when the first problem is solved, it is easy to attach events in the code of the control to the child elements, but this presents two very ugly problems: the template of the control will need to contain the child elements in question and the event will not be declared in the theme, so the behaviour would be fixed as well.

I will solve the handling of events as commands by using a solution from Samuel Jack. The article is pretty detailed, but to make the story short, one creates an attached property for each of the handled events by using a helper class:


public static class TextBoxBehaviour
{
public static readonly DependencyProperty TextChangedCommand =
EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
TextBox.TextChangedEvent, "TextChangedCommand", typeof (TextBoxBehaviour));

public static void SetTextChangedCommand(DependencyObject o, ICommand value)
{
o.SetValue(TextChangedCommand, value);
}

public static ICommand GetTextChangedCommand(DependencyObject o)
{
return o.GetValue(TextChangedCommand) as ICommand;
}
}

then by using a very simple syntax on the control that fires the event:


<TextBox ff:TextBoxBehaviour.TextChangedCommand="{Binding TextChanged}"/>



The problem regarding access to the elements in the template is solved by reading the elements by name from the template. In some situations, like when one uses a control as a source for a data control (like using a TreeView as the first item in a ComboBox), the approach will have to be more complicated, but considering the element is stored in the template of the control, something like this replaces the work that InitializeComponent does inside a UserControl:


[TemplatePart(Name = "PART_textbox", Type = typeof (TextBox))]
public class MyThemedControl : Control, ITextControl
{
private TextBox textbox;

public override void OnApplyTemplate()
{
base.OnApplyTemplate();
textbox = Template.FindName("PART_textbox", this) as TextBox;
}
...


The code is pretty straight forward: use the FrameworkTemplate.FindName method to find the elements in the OnApplyTemplate override and remember them as fields that you can access. The only weird part is the use of the TemplatePartAttribute, which is not mandatory for this to work, but is part of a pattern recommended by Microsoft. Possibly in the future tools will check for the existence of named elements in the templates and compare them against the ones declared in the control source.

The code of a demo project can be downloaded here.

Some other technologies I have used in the project:

  • the RelayCommand class, to make it easier to defined ICommand objects from code without declaring a type for each.
  • the AccessKeyScoper class that allows an IsDefault button to act locally in a panel.

If you google the net for using visual effects in WPF you are very likely to hit BitmapEffects. Well, bad news, BitmapEffect is obsolete and broken in WPF4. Instead you have Effect. The idea is to write (or download) a custom Effect for the things one would normally do using the slow (but easy to use) BitmapEffects. Also, the BitmapEffectGroup doesn't work anymore and has no alternative in WPF4. Bummer! According to Dr. WPF, the framework will try to automatically translate the older BitmapEffects to the new ones. That applies for BlurBitmapEffect and for DropShadowBitmapEffect with a Noise level of 0, for the others... you are on your own.

There were 5 default BitmapEffect classes in WPF3:
  1. BlurBitmapEffect - the WPF4 alternative is BlurEffect
  2. OuterGlowBitmapEffect - the WPF4 alternative in the Microsoft article is BlurEffect, but I have found that it can be replaced by DropShadowEffect with ShadowDepth set to 0
  3. DropShadowBitmapEffect - the WPF4 alternative is DropShadowEffect
  4. BevelBitmapEffect - the WPF4 alternative is a custom class inheriting from Effect.
  5. EmbossBitmapEffect - the WPF4 alternative is a custom class inheriting from Effect.


I found this project when googling to a simpler way of building ShaderEffects: WPF ShaderEffect Generator. Also, a discussion about a Bevel ShaderEffect here led me to this WPF shader library, but it's last release date is somewhere in March 2009.

I am using this WPF control that looks like a headered panel. On the header there is a menu, a button and then, underneath, some content that could be anything. I had this request that, when using the Tab key to navigate, the focus should first come to the button, which is not the first control in the header, then jump to the controls in the content and then jump back to the menu. In other words, to make the menu the last controls that can be reached via the Tab key inside this WPF control.

Well, in WPF there is this class called KeyboardNavigation which has some very useful attached properties: TabIndex (which defaults to int.MaxValue) and TabNavigation (which defaults to Continue). As in Windows Forms, one needs to set the TabIndex to control the navigation order, but the TabNavigation property makes it a lot more versatile and clear as well. In my case, I had to do the following:
  1. Set the entire panel control to KeyboardNavigation.TabNavigation=Local. That allowed me to control the tab index inside the control, otherwise the TabIndex value would have been global to the window
  2. Set the TabIndex of the button to 1. That made the button the first thing to be selected in case I use Tab to navigate in the panel
  3. Set the TabIndex of the content to 2. This set the controls in the content as the next controls to be accessed via the Tab key
  4. Set the TabNavigation value of the content to Local. Without this, the TabIndex value would have made no sense. First of all the content panel has IsTabStop to false and, second, any control inside it would have int.MaxValue set as TabIndex which would work globally in the main control.


This example should make it clear how to use the KeyboardNavigation properties. There is one more, called ControlTabNavigation, which has a misleading name and an ambiguous description. It is not related to a control, the Control in the name comes from the Ctrl key. In WPF one can use Ctrl-Tab to navigate an alternative order thus allowing, in this case, to go directly to the menu, then the button and then the controls in the content area.

I was trying to use a static class of attached properties that I would use inside my WPF control templates, so that every time I need to change them I would only use a setter, not copy paste the entire template and make minute changes. It worked great and I recommend this solution to everybody. So after the refactoring of my control I was shocked to see that in the production application, all my attached properties were throwing binding errors!

The solution was to explicitly use the Path= syntax in the bindings.

{Binding Path=(namespace:ClassName.Property)...
not
{Binding (namespace:ClassName.Property)...

The strange thing is that in the test application everything worked great, so what went different? Apparently the problem is that IXamlTypeResolver (used in PropertyPath) is not finding namespaces unless already registered, as explained here by Rob Relyea. The dude with that Lovecraftian name is the program manager for the WPF & Xaml Language Team.

So if one uses the namespace of the attached property before in some other context or by using the verbose syntax before, it works even with the Path keyword omitted. Not really sure why the verbose syntax works differently though.

Many a time I want that textblocks that get trimmed to display their text as a tooltip. For that, I would make a trigger to set the Tooltip value to the Text value if the textblock has been trimmed. The problem is that there is no property that shows if this is the case.

Googling a bit, I found this article, which apparently works, but also has some problems, as reported by many commenters. Even if it would have worked perfectly, my scenario is too simple to need all that code.

The idea of the original post is simple and I like it, the problem being that convoluted method that computes the width of the text in the textblock. Why would I want to redo all the work that is being done by the framework itself? The width of a textblock with TextWrapping NoWrap should be textBlock.Measure(Size(double.MaxValue,double.MaxValue)). I am sure a more complex scenario can also be serviced by this method, if the height is taken from the TextBlock, but I don't need it.

So here is the entire class, using my measuring method:
public class TextBlockService
{
static TextBlockService()
{
// Register for the SizeChanged event on all TextBlocks, even if the event was handled.
EventManager.RegisterClassHandler(typeof (TextBlock),
FrameworkElement.SizeChangedEvent,
new SizeChangedEventHandler(OnTextBlockSizeChanged),true);
}

public static readonly DependencyPropertyKey IsTextTrimmedKey =
DependencyProperty.RegisterAttachedReadOnly(
"IsTextTrimmed",
typeof (bool),
typeof (TextBlockService),
new PropertyMetadata(false)
);

public static readonly DependencyProperty IsTextTrimmedProperty =
IsTextTrimmedKey.DependencyProperty;

[AttachedPropertyBrowsableForType(typeof (TextBlock))]
public static Boolean GetIsTextTrimmed(TextBlock target)
{
return (Boolean) target.GetValue(IsTextTrimmedProperty);
}

public static void OnTextBlockSizeChanged(object sender, SizeChangedEventArgs e)
{
TextBlock textBlock = sender as TextBlock;
if (null == textBlock)
{
return;
}
textBlock.SetValue(IsTextTrimmedKey, calculateIsTextTrimmed(textBlock));
}

private static bool calculateIsTextTrimmed(TextBlock textBlock)
{
double width = textBlock.ActualWidth;
if (textBlock.TextTrimming == TextTrimming.None)
{
return false;
}
if (textBlock.TextWrapping != TextWrapping.NoWrap)
{
return false;
}
textBlock.Measure(new Size(double.MaxValue, double.MaxValue));
double totalWidth = textBlock.DesiredSize.Width;
return width < totalWidth;
}
}


This would be used with a trigger, as I said at the beginning of the post:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Style.Triggers>
<Trigger Property="Controls:TextBlockService.IsTextTrimmed" Value="True">
<Setter Property="ToolTip" Value="{Binding Text,RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>

and has 1 comment
While looking over Reflector-ed Microsoft code I noticed an attribute called FriendAccessAllowed. I googled a little and I've come up across something called Friendly Assemblies. Basically you want that your code marked as internal be visible to other assemblies that you specify. This way you restrict access for other people, but you don't need to place all your code into a huge assembly.

Microsoft tells us that to do that for .NET you need to use InternalsVisibleToAttribute to make assemblies be friends in either a signed or an unsigned way.

All nice and all, but there is no mention of this FriendAccessAllowedAttribute class. All I could find is a Microsoft patent called Logical Extensions to Intermediate Code, which says extend the runtime's notion of friend assemblies with a "FriendAccessAllowed" attribute, and only include internal methods marked with this attribute in the reference assembly (instead of known implementations in which all internal methods are included in the assembly).. In other words, specify explicitly which of the internal members you want exposed to your friends.

There is another question about this on StackOverflow, which says as much, as well, but nothing actually usable.

As far as I can see, Microsoft uses this in the WPF and Silverlight frameworks only and the funny thing is... the attribute is internal. :)

If you search the net for a skinnable application, you get a lot of answers and pages that seem to hit the spot right on. If you are looking for a skinnable control library, though, the hit count drops considerably. This post is about my adventures with resource keys and the solution for a problem that has plagued me for more than a day of work, plus some weird behaviour that I have as yet no explanation for.

The article is pretty long, so here is the short and dirty version:
  • Do not use Colors as dynamic resources, use Brushes
  • If you want to use resources from a theme dictionary outside the assembly, you must give them keys of the type ComponentResourceKey
  • The type you use in the constructor of the ComponentResourceKey class or in the markup extension of the same name must be in the same assembly where the resource is!


The scenario is as follows:
  • there is an application that needs to change some of its visual characteristics dynamically during run time
  • the application uses a custom control library
  • other applications/modules should use the same themeing mechanism
  • other applications will use the same control library


The solution seemed simple enough:
  • create a static class to hold the string keys for the resources I want to define dynamically
  • create a shared resources dictionary in the controls theme, using those keys
  • use the shared dictionary in the controls theme
  • create another shared resources dictionary in the applications, or use only the ones already defined in the control library
  • use the application shared dictionaries in the application styles
  • programatically add/remove resources directly in Application.Current.Resources to override the already defined resources


I have tested this solution in a not very thorough manner and found it working. Of course, some of the problems needed solving.

The first issue is that theme level resources are not found from outside the assembly unless defined using a ComponentResourceKey as the key of the resources. This special class receives two parameters in the constructor: a type and an object that is a "regular" resource key. So instead of using a string, as one would probably use in an application style, you use a component resource key that receives a type and that string. A small test confirmed that a resource is not found at the application level using FindResource if only defined with a string as key and that it is found if using a ComponentResourceKey.

The second issue was that in order for a resource to be dynamically changed at runtime it needed to be defined as a DynamicResource, not a StaticResource which is only resolved at compile time. Not a huge problem. However, if one has defined some brushes in the control library and then referenced them in all the styles, then it would also work to redefine those brushes to use colors dynamically, and then all one has to do is change the colors. That would also prove advantageous if one needs a variety of brushes using the same colors, like gradients or some lighter version of the same color.

This leads to Problem number 1: Dynamically changing Color resources worked for foreground brushes, for background brushes, but not for border brushes! So you have a textbox and you define Background, Foreground and BorderBrush properties using StaticResource on brushes that themselves define their Color as a DynamicResource. You change the colors (adding new resources at the application level of the type Color) and you see the Background and Foreground changing, but the border staying unchanged.

I have no idea why that happened. Some information that I got researching this problem was related to Shared resources, but changing the shared status of brushes or even colors to true or false did not change anything. Another idea was that his was related to their Frozen status but, as there was no difference between the Foreground and BorderBrush brushes (I even used the same brush at the same time on both properties), I've decided that it wasn't the case.

BorderBrush is a dependency property belonging to the Border element, while Foreground and Background belong to the TextElement and Panel elements, respectively, and other elements add themselves as owners to them. In the case of the Border element that I have tested this weird behaviour on, BorderBrush is its own dependency property, while Background is the Panel.BackgroundProperty. I also thought that it may have something to do with FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender, but both properties are registered with this flag.

After some searching, I found that the Border element caches internally Pen objects that are used to render the different border sides. They use the same brush as the border, though, and so, even if this is the best candidate for the cause of the problem, I still don't know what the hell was going on.

The solution for this problem was (to my chagrin) to use the brushes themselves as dynamic resources. Well, it was a setback, seeing how the resources I want to change are colors and now I am forced to create brushes and, thus, stain this process with the responsibility of knowing what kind of brushes are needed for my controls and applications, but I could live with it. After all, that was all WPF stuff, so I could separate it at least from the static class holding the keys of the characteristics I wanted to change dynamically.

Problem number 2: using as a key in XAML a class with a long name which uses a constructor that receives a type and a static constant/property of a class is ugly and unwieldy. The solution for this problem was to create another static class that would hold the keys for the brushes. Each brush would have a property in the class that returns a ComponentResourceKey object that uses the classes own type as the first parameter and the constant string key from the static string key class.

That effectively changes stuff looking like {DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type UI:ResourceScheme},{x:Static UI:ResourceScheme.ControlBackgroundKey}}} to {DynamicResource {x:Static WPF:ThemeResources.ControlBackgroundBrushKey}}. Still a mouthful, but manageable.

Problem number 3 (the big one): it doesn't work! The brushes I so carefully created in the theme are not getting set in the controls, not the mention the application. What confounded the issue even more is that if I changed DynamicResource to StaticResource in the control templates I would see the brushes rendered correctly. I wouldn't be able to change them dynamically afterwards, but how come StaticResource works and DynamicResource doesn't!? Stranger still, adding/removing resources with the same key in the application resources dictionary (the mechanism that was supposed to dynamically change the aspect of the application) worked! Everything was working perfectly, and only the default brushes defined in the theme were not loaded!

The solution for this was (after hours of trial, error, googling, suicidal thoughts and starting all over again) to use a type from the control library in the ResourceComponentKey constructor! You see, I had placed both static key classes in a separate assembly from the control library. Moving the WPF related resource key class in the control library fixed everything!

Now, you may be wondering why that worked, and so do I. As I see it, if you define a template and a brush in a theme and the template is loaded and applied, then the brush should also be loaded. If FindResource did not find the brush, then it must be that either the brush was not loaded due to some internal requirements of the ResourceComponentKey class or that it was loaded and then the key I was using was different from the one I was using when asking for it or, as Akash Kava tried to explain to me on StackOverflow, it will only find in the resource dictionaries of its own logical parental tree.

I have dismissed the second option, as the ComponentResourceKey has an Equals override that simply compares type and key. There cannot be two instances of the same type and the key is a string constant, so there should be no ambiguity on whether two resource keys are equal.

What remains are that either the ComponentResourceKey class messes things up or that the resources using resource keys are placed in "logical trees" based on the target type of the ComponentResourceKey. I have looked for the usages of the ComponentResourceKey class and all I could find was something in a BaseHashHelper that seemed related to ItemsControl or CollectionView, so I don't think that's it. I also looked at the implementation of FindResource, but found nothing that I could understand to cause this.

As a funny side note, as I was going about this task I was trying to get inspiration from the way the SystemColors class worked. The resource keys related to colors that were returned were not of the type ComponentResourceKey, but of SystemResourceKey, both inheriting from ResourceKey nonetheless. I have noticed no significant piece of code in the (of course internal) SystemResourceKey class, however I did find code in FindResource that checked if the key is of type SystemResourceKey and did something with it. Nice, Microsoft! However, that was not the cause of the problem either.

After knowing what to look for, I did find on the Microsoft article about the ComponentResourceKey markup extension that The TypeInTargetAssembly identifies a type that exists in the target assembly where the resource is actually defined. In the article about the ComponentResourceKey class, they say If you want an easily accessible key, you can define a static property on your control class code that returns a ComponentResourceKey, constructed with a TypeInTargetAssembly that exists in the external resource assembly, and a ResourceId. Too bad they hid this information in the Remarks section and not in the definition of the Type parameter.

Congratulations if you have read so far! You must be really passionate about programming or desperate like me to find an answer to these questions. I hope this article has enlightened you and, if not, that you will find the answers and then get back to me :)

Update February 2016:If you just want to disable R#, like it is not installed, go to Tools → Options → ReSharper → Suspend/Resume

I've been using ReSharper (R#) for a long time now and I can tell you that if you are a Visual Studio C# developer and you are not using it, you are missing out. These guys must have the greatest job in the world: develop for developers. Or could it be the worst job, since doctors always make the worst patients? anyway...

I have been preaching about ReSharper for about 4 years now and the most common complaint from people new to it is that it makes things go slowly in certain situations. The thing is, R# is doing so much stuff in the background, that I find it amazing it moves so fast as it does. It is a valid complaint to want to have the same speed of typing and moving around that you have in the normal Visual Studio environment and still have the many features provided by ReSharper.

So, my solution was to have a command to "pause" the ReSharper analysis until I need it. The scenario would be:
  • Suspend analysis and regain swiftness of typing
  • Write your fingers off, since you already know what to type and even Intellisense feels like slowing you down
  • Resume the analysis and get all the R# goodness
In other words, something like writing your code in notepad and then copy pasting it all in the VS window.

Well, as most of the time, the R# have thought about it already! You have two possible options. One is using the commands ReSharper_Suspend, ReSharper_Resume and ReSharper_ToggleSuspended. You can either bind them in the Tools -> Options -> Environment -> Keyboard to whatever combination you desire, or go to Tools -> Options -> ReSharper -> General and use the Suspend button. This is equivalent to enabling/disabling the ReSharper addon. Since it is a very large addon and needs a lot of resources and hooks, this option is terribly slow. It does have the advantage of freeing all memory used by R#. The second option is more what I was having in mind: the command ReSharper_EnableDaemon. It sounds kind of like "Release the Kraken!" and it works in a similar way. What it does is suspend/enable code analysis on the current file! It is already bound as a global shortcut on Ctrl-Alt-Shift-8. It works almost instantly and enables the scenario I wanted.

Bottom line: Ctrl-Alt-Shift-8 to suspend/resume code analysis on the current file so you can type like your livelyhood depends on it. Again, thank you, JetBrains!

Update: It seems on older versions of ReSharper (not 5), the shortcut is Ctrl-8.

and has 1 comment
I wanted to open a dialog in .NET asking for an image file and so I needed to construct a filter with all supported image types. Strangely enough, I didn't find it on Google, so I did it myself. Here is a piece of code that gets the filter string for you:

private string getImageFilter()
{
StringBuilder sb=new StringBuilder();
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo info in codecs)
{
if (sb.Length > 0)
sb.Append(";");
sb.Append(info.FilenameExtension);
}
return sb.ToString();
}
As you can see, it enumerated through the image encoders list and creates the extension list. The filter, then, is obtained as

filter = string.Format(
"Image Files({0})|{0}|All files (*.*)|*.*",
getImageFilter())

Before using it, though, here is the (surprisingly disappointing) filter string: *.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.TIF;*.TIFF;*.PNG
Kind of short, isn't it?

To simply quote and link: Unfortunately, this is where the SharedSizeGroup method breaks down. If you want to have a shared Grid that uses the whole available width and automatically adjusts when that space changes you're going to need a different method. A column set to * in a shared group acts just like an Auto column and won't fill or stay within the given space. Taken from John Bowen's blog.

and has 6 comments
I have been trying to build this setup for a project I made, using WiX, the new Microsoft paradigm for setup packages. So I did what any programmer would do: copy paste from a previously working setup! :) However, there was a small change I needed to implement, as it was a .NET4.0 project. I built the setup, compiled it, ran the MSI and kaboom!

Here is a piece of the log file:
Action 15:34:48: FetchDatabasesAction. 
Action start 15:34:48: FetchDatabasesAction.
MSI (c) (A0:14) [15:34:48:172]: Invoking remote custom action. DLL: C:\DOCUME~1\siderite\LOCALS~1\Temp\MSI21CF.tmp, Entrypoint: FetchDatabases
MSI (c) (A0:68) [15:34:48:204]: Cloaking enabled.
MSI (c) (A0:68) [15:34:48:219]: Attempting to enable all disabled privileges before calling Install on Server
MSI (c) (A0:68) [15:34:48:251]: Connected to service for CA interface.
Action ended 15:34:48: FetchDatabasesAction. Return value 3.
DEBUG: Error 2896: Executing action FetchDatabasesAction failed.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2896. The arguments are: FetchDatabasesAction, ,
Action ended 15:34:48: WelcomeDlg. Return value 3.
MSI (c) (A0:3C) [15:34:48:516]: Doing action: FatalError

In order to get the log of an MSI installation use this syntax:
msiexec /i YourSetup.msi /l*vvv! msiexec.log
vvv is used to specify verbosity, the ! sign is used to specify that the log should be flushed after each line.

As you can notice, the error is a numeric error (2896) and nothing else. Googling it you get to a lot of people having security issues with it on Vista and Windows 7, but I have Windows XP on my computer. The error message descriptions pretty much says what the log does: Custom action failed. Adding message boxes and System.Diagnostics.Debugger.Launch(); didn't have any effect at all. It seemed the custom action was not even executed!

After hours of dispair, I found what the problem was: A custom action is specified in a DLL which has a config file containing this:

<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
which specifies for the MSI installer which version of the .NET framework to use for the custom action. Not specifying it leads to a kind of version autodetect, which takes into account the version of the msiexec tool rather than the custom action dll. It is highly recommended to not omit it. The problem I had was that I had changed the target of the custom action to .NET 4.0 and had also changed the config file to:

<startup>
<!--<supportedRuntime version="v2.0.50727"/>-->
<supportedRuntime version="v4.0.30319.1"/>
</startup>


Changing the version to NET3.5 and adding the original config string fixed it. However, I am still unsure on what are the steps to take in order to make the 4.0 Custom Action work. I have tried both 4.0.30319 and 4.0.30319.1 versions (the framework version folder name and the version of the mscorlib.dll file in the .NET 4.0 framework). I have tried v4.0 only and even removed the version altogether, to no avail.

In the end, I opened the WiX3.5 sources and looked for a config file. I found one that had this:

<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
<supportedRuntime version="v2.0.50727" />
</startup>
As you can see, there is an extended supportedRuntime syntax in the 4.0 case, but that is not really relevant. The thing that makes it all work is useLegacyV2RuntimeActivationPolicy="true"!

So shame on whoever wrote msiexec for not specifying the actual problems that make a setup fail, and a curse on whoever decided to display a numeric code for an error, rather than trying to write an as verbose a description as possible. I hope people will find this post when facing the same problem and not waste three hours or more on a simple and idiotic problem.

Update: Thanks to Tim Fischer from Tangible, I got to solve all the problems described in the post below using VolatileAssembly and macros like $(SolutionDir) or $(ProjectDir).

When T4 (Text Template Transformation Toolkit) appeared as a third party toolkit that you could install on Visual Studio 2008, I thought to myself that it is a cool concept, but I didn't get to actually use it. Now it is included in Visual Studio 2010 and I had the opportunity to use it in a project.

The idea is to automatically create code classes and other files directly in Visual Studio, integrated so that the files are generated when saving the template. All in all a wonderful idea... but it doesn't work. Well, I may be exaggerating a bit, but my beginning experience has been off putting. I did manage to solve all the problems, though, and this is what this blog post is about.

First of all, there is the issue of intellisense. I am using ReSharper with my Visual Studio, so the expectations for the computer knowing what I am doing are pretty high. In the .tt (the default extension for T4) files you don't have any. The solution for this is to use the Tangible T4 editor (I think they were going for a fifth T here) that comes as a Visual Studio addon for VS2008 and VS2010. Fortunately, there is a free version. Unfortunately, it doesn't do intellisense on your own libraries unless you buy the priced one. Also, the intellisense is years behind the one provided by ReSharper or even the default Visual Studio one and the actions one can do automatically on code in a T4 template are pretty limited.

The second problem was when trying to link to an assembly using a relative path to the .tt file. The Assembly directive supports either the name of an assembly loaded in the GAC or a rooted path. Fortunately, the VS2010 version of the T4 engine supports macros like $(SolutionDir). I don't know if it supports all Visual Studio build macros in the link, but the path ones are certainly there.

Here is how you use it. Instead of


<#@ Assembly Name="Siderite.Contract.dll" #>

use


<#@ Assembly Name="$(SolutionDir)/Assemblies/Siderite.Contract.dll" #>



The third problem was that using an assembly directive locked the assembly used until you either reopened the solution or renamed the assembly file. That proved very limiting when using assemblies that needed compiling in the same solution.

This can be solved by installing the T4 Toolbox and using the VolatileAssembly directive. Actually, on the link above from Oleg Sych you can also find a bit advising using the T4 toolbox VolatileAssembly directive in the Assembly Locking section.

Here is how you use it. Instead of


<#@ Assembly Name="$(SolutionDir)/Assemblies/Siderite.Contract.dll" #>

use


<#@ VolatileAssembly
processor="T4Toolbox.VolatileAssemblyProcessor"
name="$(SolutionDir)/Assemblies/Siderite.Contract.dll" #>

As you can see you need to specify the processor (the VolatileAssemblyProcessor would have been installed by the T4 Toolbox) and you can use macros to get to a relative rooted path.

So thanks to the eforts of Oleg and Tim here, we can actually use T4. It would have been terribly akward to work with the solution in the obsolete section below. The Tangible guys have a learning T4 section on their site as well. I guess that using the resources there would have spared me from a day and a half wasted on this.

The following is obsolete due to the solutions described above, but it is still an informative read and may provide solutions for similar problems.

Click to expand.



Tips And Tricks:
Problem: the T4 generated file has some unexplained empty lines before the start of the text.
Solution: Remove any spaces from the end of lines. Amazingly so, some white space at the end of some of the lines were translated as empty lines in the resulting .tt.

Problem: The code is not aligned properly
Solution: Well, it should be obvious, but empty spaces before the T4 tags are translated as empty spaces in the resulting .tt file. In other words, stuff like <# ... should not be preceded by any indenting. It will make the template look a bit funny, but the resulting template will look ok. If you dislike the way the intending looks in the template, move the indent space in the tag, where it will be treated as empty space in the T4 code.