ClickOnce and DevExpress components deployment

Let’s say you’ve build a WinForms application and put some DevExpress (or any other 3rd party controls installed in GAC I suppose) controls in there. At some point you have to deploy the application and let’s say you’ll use ClickOnce technology. Its easy, go to Project Properties/Publish tab, select where to publish and click Publish button. The next step is to try the application and of course you try it at your development computer – it works, no surprise there. However, when your client runs it on his computer it will most probably throw some sort of exception at the very beginning. Besides the obvious Murphy law involvement, why’s that? After all it worked on *development* computer.

There are two problems in this process.

1. ClickOnce doesn’t include 3rd party assemblies by default. This is probably true for all 3rd party assemblies that reside in GAC on development computer or in other words, those which are marked with CopyLocal=false (I admit it, I never researched in details). It should include those who are marked CopyLocal=true. Now, if you look at your Application Files in Publish tab of Project Properties you’ll see that all three DevExpress assemblies are marked with Publish Status = Prerequisite (Auto) flag – it means that your application expects those assemblies already installed on target machine:

pre

To include them in your deployment package change their Publish Status flag to Include. Like this:

post

All required assemblies will be published to client’s computer and the application will work, or at least will work as good or as bad as on development computer.

2. Your testing process isn’t good. You should always test deployment scenarios on non-development machine(s). VMWare Workstation is of great help. Besides the great virtualization desktop platform it also support integration in Visual Studio itself so you can pretty easily launch application in guest OS or even remotely debug it and even record the session. The other virtualization option on desktop is MS’ VirtualPC, an inferior application but free. You could use virtualization servers as well (MS HyperV,  VMWare Server, etc.).

That’s it.

A better call to Control.Invoke

Whenever one needs to interact with WinForms UI from within another thread (the one that didn't create the UI controls) one has to rely on the Control.Invoke (or BeginInvoke/EndInvoke pair) method. Otherwise one gets an InvalidOperationException exception with message “Cross-thread operation not valid: Control ‘name here’ accessed from a thread other than the thread it was created on”. This happens because WinForms (and .net framework in general) isn’t thread safe.

Let’s say I want to know how many controls are on the form. I’d do it like this (Form f holds the instance of the Form created in some thread):

public static int GetControlsCount(Form f)
{
if (f.InvokeRequired)
return (int)f.Invoke(new Func<Form, int>(GetControlsCount), f);
else
return f.Controls.Count;
}
...
int count = GetControlsCount(f);

This way the method GetControlsCount is thread safe. That’s fine. But what should I do if I require to access many methods in such a thread safe way (I’ll blog about the reason I need it in a future post)? Creating this kind of wrapper for every different method I need to call would be kind of boring at best and difficult to maintain, don’t you think?

So I created a generic method instead, like this:

public static TRet InvokeSync<TRet>(Control control, Func<TRet> func)
{
if (control.InvokeRequired)
return (TRet)control.Invoke(func);
else
return func();
}
...
int count = InvokeSync<int>(f, () => f.Controls.Count);

This is much better because I don’t need to create a wrapper for each method – instead I merely provide a delegate (of type Func<int> in my case). There are two drawbacks to this approach.

1. It won’t work with different number of parameters nor it will work with methods (= actions) that don’t return a value. The only workaround is to create various similar methods that accepts different argument number and return either a result or no result (void). Here is a bunch of such variations:

public static void InvokeSync(Control control, Action action)
{
if (control.InvokeRequired)
control.Invoke(action);
else
action();
}
public static void InvokeSync<T>(Control control, Action<T> action, T argument)
{
if (control.InvokeRequired)
control.Invoke(action, argument);
else
action(argument);
}
public static TRet InvokeSync<T, TRet>(Control control, Func<T, TRet> func, T argument)
{
if (control.InvokeRequired)
return (TRet)control.Invoke(func, argument);
else
return func(argument);
}
public static TRet InvokeSync<T1, T2, TRet>(Control control, Func<T1, T2, TRet> func, T1 argument1, T2 argument2)
{
if (control.InvokeRequired)
return (TRet)control.Invoke(func, argument1, argument2);
else
return func(argument1, argument2);
}

2. Passing Control parameter (which is required to do the synchronization) is such pre .net 3.5-ish. Instead extensions methods can be used, like this:

public static class Extender
{
public static TRet InvokeSync<TRet>(this Control c, Func<TRet> func)
{
if (c.InvokeRequired)
return (TRet)c.Invoke(func);
else
return func();
}

public static void InvokeSync(this Control c, Action func)
{
if (c.InvokeRequired)
c.Invoke(func);
else
func();
}
}

So the final version of the call to InvokeSync looks even nicer:

int count = f.InvokeSync<int>(() => f.Controls.Count);

That’s it.

InvokeSyncExtender.zip (572.00 bytes)

Packing assemblies to a single file for Righthand.Dataset.Visualizer

A while ago I’ve created Righthand.DataSet.Visualizer, an advanced DataSet visualizer. Today I’ve added support for displaying a single table as well. It wasn’t a big deal but I guess people will find it useful.

Now, there is one things I weren’t too happy about until today: I reference a lot of DevExpress assemblies and I have to redistribute all those assemblies along mine two (my visualizer comes in form of two assemblies). Which makes a lot of assemblies in total and even worse, if two visualizers use slightly different DevExpress versions you are in for a trouble.

So I’ve decided to pack everything to a single file. ILMerge, a free assembly merging tool from Microsoft, won’t work for me since it has problems with reference to Microsoft.VisualStudio.DebuggerVisualizers even though I don’t want to redistribute it. So I tried Xenocode Postbuild for .NET which does all sort of hacky things with .net assemblies, it even allows to create a setup that doesn’t require .net framework installed at the target machine. Among other features (obfuscation, optimization, etc.) it provides an assembly merging option that I successfully used in my case. Here are the required steps for my case:

1. Start Xenocode Postbuild for .NET, click on Application tab. Use Add… button to add required assemblies to pack together (you can add assemblies individually or pick most important ones and then use Scan Dependencies button to add referenced ones):

application

2. If you want only to pack assemblies then use Null – For test and debugging purposes or any other preset you want, just make sure you set other options appropriately.

presets

 

 

 

3. On the Protection tab I did uncheck all metadata obfuscation (since I am not after obfuscation here) by right clicking on the root node and selecting Unselect Tree menu item. I don’t use any Disassembler Suppression either. I left moderate code obfuscation (level 3 in scale 0..4), just for testing – this option shouldn’t cause any trouble since it should keep functionality the same. If there are problems with the later it means that the tool sucks heavily.

protection

4. Clear all checkboxes in Optimize tab.

5. On the Output tab I made sure that Single application executable option in Link and Code Generation group is selected and Righthand.DebugerVisualizer.Dataset.Visualizer assembly is the main one. I also selected .\Setup for the output folder.

output

6. By clicking Xenocode Application button the final, single file, output is written to the disk.

And that’s it. I got a single file with all required assemblies packed together. Just that easy. Note that I intentionally used only a fraction of Postbuild power.

If you use frequently Postbuild you should also consider using Final Builder tool, an automated build and release management tool that supports Postbuild out of the box (I am sure other such tools support Postbuild as well).

And finally, here is the updated visualizer:

RightHand.DebugerVisualizer.Dataset.Visualizer 0.9.14.zip (7.60 mb)

Let me know if there are any problems or if you have any improvement wish.

Upgraded BlogEngine from 1.4.5 to 1.5

I have just upgraded BlogEngine.net, an excellent blog engine which hosts this blog, from 1.4.5 to 1.5. The process was more or less smooth as I'll describe in next points:

  1. Download Blogengine.net Web from download page.
  2. Read upgrade tutorial.
  3. Make a backup of current installation and database if you are using it.
  4. Delete all files and folders except for App_Data.
  5. Copy new files.
  6. Copy extensions, widgets and other custom data from backup you made in #3.
  7. Upgrade database structure with script found in Setup/SQLServer folder (or any other if you are using other database).
  8. Open web.config and replace the connectionString (I am using SQL Server as a storage).
  9. Replace all occurences of defaultProvider attribute to "DbBlogProvider" (blogProvider, membership, roleManager).
  10. Make sure App_Data is writable for Blogengine.net.

I think that's pretty much it for my upgrade process.

Modern bicycle equipment

I have been bicycling for almost two decades now. I started with a Cannondale M700 cross country not-suspended mountain bike which I still own and use for non demanding terrain such as roads.

Every (mountain) bicycle should have a bicycle computer and looking back I still remember my first bicycle “computer”, a cheap wired one, I can’t remember the manufacturer. Bicycle computers evolved since then and so did other technologies. Looking at my current bicycle equipment yields this picture, originally drawn by Tevž, my six year son and modified by me (added equipment and descriptions):

me and bike p

The blue arrows shows wireless communication while the orange boxes describes the equipment which consists of two groups:

1. Bicycle computer: Garmin Edge 305 device which is a GPS receiver combined with heart rate and cadence (pedal rotations) monitoring and barometric sensor for altitude reading as well. The communication with monitors is through proprietary ANT+ wireless protocol so no wires are involved (barometric sensor is built in). The base unit shows all kind of data based on those four inputs and it has quite enough of memory as well – so I can store routes to my PC. It doesn’t feature navigation though – you’d need to buy a newer and more expensive 705 model, for that.

2. Pocket PC which serves three purposes: it plays music or podcasts to the Motorola Rokr S9 bluetooth headset (depends on my mood), it allows me to use headset in hands free mode to make or receive phone calls and finally, it transmits all sort of data (i.e. position obtained by GPS sensor – not Garmin’s but its own) back to my server. Or better, it could transmit since I haven’t found time yet to implement it. Sure, I could use one of the applications available out there but then I’d have to send the data to their server which I don’t want to.

So, once I finish a daily exercise I transfer the data stored in Edge 305 to my PC through USB cable using Sport Tracks application. Sport tracks is an excellent application that keeps track of your exercises and it is not bound to bicycling in any way. It is a topic of a post on its own but if you want to keep a logbook of your exercises you should really take a look – it is free. Anyway, here is a screenshot of my last exercise as shown by Sport Tracks:

 

 

sporttracks

Is there anything I am missing in my equipment? Sure, there are some things I’d like to happen or to have.

  1. Garmin’s monitoring equipment should use bluetooth protocol so I could read them from any computer. This is unlikely going to happen but at least it is using standardized protocol ANT+. There is at least one standalone receiver with software made for iPhone out there.
  2. Edge unit should implement bluetooth protocol so I could read data directly from it to my Pocket PC. Either this or #1 which is better.
  3. One day I’d like to mount a power meter as well but there are two economical obstacles: those are very expensive ($1500+) and I’d have to buy Edge 705 unit as well to read its data.

My favorite features in upcomming Visual Studio 2010/.net 4.0

The following two are my favorite features comming with .net 4.0 and Visual Studio 2010:

  • parallel extensions - a great and easy way to utilize those idle cores in your multi core machines. It might be as easy as adding an AsParallel() extension method to a LINQ query. I even did a bunch of presentations on the topic, the last one at NT Konferenca 2009.
  • code contracts - improving the code in both design time (static analysis!) and runtime (note: albeit this feature is a part of .net 4.0 beta you have to download the package to install design time support for Visual Studio 2010 beta. This step is supposed to be redundant for RTM or sooner).
Perhaps there are other better features however these two are the ones I am most interested *currently*. So, what are yours?