Jesper Niedermann's .NET Blog
about .NET and related technologies RSS 2.0
# Wednesday, 15 July 2009

Just released version 1.2 of SolZip my convenient tool for Zipping Visual Studio 2008 solutions

The major is a single install for SolZipMME, so you won't have to install ManagedMenuExtensions beforehand.

The release notes are here:

  1. Bug Fix: when multiple projects where referering to the same file it was added to the archive multiple times.
  2. SolZipMME uses SaveFileDialog instead of FolderBrowserDialog for Zip files.
  3. A single file installer for SolZipMME.
  4. Clipboard functionality now works on Vista / Windows Server 2008.
  5. SolZipGuidance changed. The menu will no longer appear on projects that are not C# projects. SolZipMME not changed.
  6. Support for $(SolutionDir) and $(ProjectDir) placeholders added
  7. Now works on Windows Vista even if UAC is not turned off

Enjoy...

Wednesday, 15 July 2009 16:05:27 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Tools | Visual Studio
# Monday, 29 June 2009

I just released version 1.1 of SolZip which can be downloaded from the download page at the SolZip site.

The new action packed version contains one major improvement, one bug fix, and a few name changes:

  1. Now Source Control bindings for TFS and SCC can be removed from sln and csproj files. The default for all 3 UI's is that the bindings are removed, but you can optionally choose not to remove them. Feel free to contact me if you need bindings from other source control vendors removed.
  2. A bug fixed that made WinZip clients give a warning when unzipping certain archives made by SolZip. The warning was given when there was .. (2 dots) in a path in one of the zipped files.
  3. The Name SunZip.exe for the commandline tool was changed to SolZip.exe. Because SunZip sounded too much like UnZip.
  4. The Name SolutionZipper changed to SolZip everywhere. Except for SolutionZipper.dll which has been changed to SolZipBasis.dll

In the next version I will try to include ManagedMenuExtensions in the install so you won't have to run more than one setup to install SolZipMME.

Enjoy the new version :O)

Monday, 29 June 2009 20:44:48 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Tools | Visual Studio
# Thursday, 18 June 2009

Here is my take on the Best practice Dispose pattern for most situations. It is heavily influenced by Juval Löwy from IDesigns book "Programming .NET Components", and some other sources which I no longer remember, since I made it a few years ago and have stuck to it ever since. Here it is:

public class Class1 : IDisposable
{
private bool m_IsDisposed;

~Class1()
{
Dispose(false);
}


[MethodImpl(MethodImplOptions.Synchronized)]
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool isDisposing)
{
if (m_IsDisposed)
return;

if (isDisposing)
{
FreeManagedRessources();
}
FreeUnmanagedRessources();
m_IsDisposed = true;
}

protected virtual void FreeManagedRessources()
{
//Free managed ressources here. Typically by calling Dispose on them
}

protected virtual void FreeUnmanagedRessources()
{
//Free unmanaged ressources here.
}
}

Another thing is that you can inherit the class and override the FreeManagedRessources and FreeUnmanagedRessources as needed.

Thursday, 18 June 2009 21:38:51 (GMT Daylight Time, UTC+01:00)  #    Comments [6] -
.NET
# Monday, 15 June 2009

I just released a new codeplex project SolutionZipper which makes it a breeze to zip compress your visual studio solutions and projects. "What's wrong with WinZip you might Ask". Well WinZip has no knowledge of Visual Studio Solutions, which means it will compress everything in the folder, including bin / obj folders and other random debris.

I accomplish the compression by using the following algorithm:

1. Iterate over all items and projects in the sln file and zip each of these.
2. Zip the sln file itself.
3. Iterate over all items in the csproj files and zip each of these. The iteration is done using Linq to Xml of course.
4. Zip the csproj file itself.

As you might have guessed SolutionZipper only works for C# projects, and is only tested with VS2008.

I offer three UI's for SolutionZipper

SunZip - A commandline tool.

 

SolZipMME - Providing Right click menus for Visual Studio 2008 using Managed Menu Extensions .

 

SolZipGuidance - Providing Right click menus for Visual Studio 2008 using Guidance Automation (GAX).

 

For the actual zipping I use the excellent open source framework SharpZipLib.

Monday, 15 June 2009 22:46:31 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Tools | Visual Studio
# Sunday, 14 June 2009

I was using my codeplex project ManagedMenuExtensions recently when I realized that it threw an Exception, when clicking on a menu attached to a C# project under a solution folder. The reason was that the object which normally contained an EnvDTE.Project when a project was clicked contained null, when this project was contained in a solution folder.

I normally use this code to get at the selected project (m_VSStudio is the DTE object of the current solution):

private UIHierarchyItem SelectedItem
{
get
{
UIHierarchy uiHierarchy = m_VSStudio.ToolWindows.SolutionExplorer;
if(uiHierarchy == null)
return null;

object[] items = uiHierarchy.SelectedItems as object[];
if(items == null || items.Length == 0)
return null;

return items[0] as UIHierarchyItem;
}
}

The SelectedItem.Object of type object now contains a EnvDTE.Solution object if the solution is selected in the solution explorer, and guess what :O) it contains an EnvDTE.Project if a project is selected. It is this SelectedItem.Object that contains null, if the project is contained in a solution folder.

I googled this problem and found others who had the same problem, but none with a solution, so I had to come up with my own. I don't know if this behaviour is by design from Microsoft, or if it is a bug.

My Solution

Normally I would test if a project is selected with this code:

var project = SelectedItem.Object as Project;
if (project != null)
{
//Do something with the project
}

Now I use this code instead:

Project project = GetProject(SelectedItem.Object);
if (project != null)
{
//Do something with the project
}

Where I implemented GetProject(...) as:

private Project GetProject(object selectedItemObject)
{
var project = selectedItemObject as Project;
if (project != null)
return project;

var item = selectedItemObject as ProjectItem;
if (item == null)
return null;

return item.SubProject;
}

Not exactly beautiful, but that is to be expected when playing with Visual Studios AddIn model, and the kind of thing I try to hide in ManagedMenuExtensions. I haven't had a chance to look at Visual Studio 2010 yet, one could hope that they have done a better job of hiding the ugly underlying COM stuff.

 

Anyway, I hope this helps the next person who tries to search for a workaround for this rather weird behaviour.

Sunday, 14 June 2009 18:33:04 (GMT Daylight Time, UTC+01:00)  #    Comments [3] -
.NET | Tips & Tricks | Visual Studio
# Wednesday, 06 May 2009

My favourite RSS reader is GreatNews. First of all it is a standalone application, and secondly it is portable, which means I can install it on a USB key or better yet in my Dropbox which is what I do.

Well to be fair it is not portable in the purist way because it caches some stuff on the computers harddrive, but that is only for performance, so functionally GreatNews IS portable.

And GreatNews is very fast, which is just one more reason to love it.

In fact it has only one drawback, the database tends to get corrupt every 2-3 months, and there is no obvious way to repair it. I guess it will be corrected at some point in time (?) but for now it nearly made me give up on this otherwise great product.

After some googling I found that GreatNews uses an sqlite database called newsfeed.db. I couldn't really find a repair tool for it, even though I found a page which lots of tools for sqlite.

So I had to repair it in a more indirect way.

I downloaded one called sqliteman and with this I was able to make a new database called newsfeed.db and export all content from the old database and import it to the new one.

One nice sideeffect was that the database was only 1/10 in size after the import. Apparently either GreatNews or Sqllite tends to bloat the database.

After the import I replaced the old database with the new one (you should make a backup of course !), and viola it worked perfectly. So once more I am a happy user of GreatNews :O).

I cannot guarantee that this method will work for you too, perhaps I was just lucky. I advice you to keep your backup of the old newsfeed.db just in case.

P.S: To export the database you just choose "Dump database..." as shown below in a screenshot from sqliteman, which generates an SQL script that can be opened and run in the new database:

newsfeed1

Wednesday, 06 May 2009 21:34:53 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Tips & Tricks | Tools
# Friday, 01 May 2009

If you want to Execute something on each element of the result of a Linq expression. You can either loop over the result using foreach(...) or turn the result into a List using .ToList(), and then use .Foreach(...) on the resulting list. Like this:

(from excep in ErrorList
where excep is ArgumentException select excep)
.ToList().ForEach(e => Console.WriteLine(e.Message));

This is ugly, and I prefer to make my own Extension method for IEnumerable<T> called Execute(...):

public static void Execute<T>(this IEnumerable<T> list, Action<T> action)
{
foreach(T element in list)
{
action(element);
}
}

This means you can do this instead:

(from excep in ErrorList
where excep is ArgumentException select excep)
.Execute(e => Console.WriteLine(e.Message));

Back in the days when I used Linq in a program for the first time, I wondered why there was no way to execute an action on each element of a list, so I implemented the Execute method.

It was only later that I discovered that the default way was .ToList().Foreach(...)

I must say I still prefer my original approach.

BTW: In a small none scientific test I have tested the two approaches.

With Linq To Objects iterating over 100000 integers and printing them to the Console takes about 21 seconds with the Foreach method and about 20 seconds with the Execute method, so it is even faster at least for this particular example. Though nothing to get excited about. :O)

The test was done in a Vista VPC with VS2008,

Small performance test: LinqPerfTest.zip

Friday, 01 May 2009 21:12:40 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | Linq | Tips & Tricks
# Tuesday, 14 April 2009

This site uses Google Adsense. And Google has informed me that I have to update my privacy policy, because they have started to use the DoubleClick DART cookie. I didn't really have one till now. But here it is containing all the legal mumbo jumbo that Google requires:

This site uses Google adsense to serve ads when you visit www.niedermann.dk. Google may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by Google, click here.

Tuesday, 14 April 2009 10:46:22 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Tuesday, 07 April 2009

I recently was in a company where I created the coding standard. Mostly by referring to the great standard from IDesign but with a twist of company specific things. When C#3.0 came out I couldn't find any coding standard material on the new stuff out there on the web. So I was forced to think...

My thoughts on the var keyword, is that it should be used extensively. But I place a restriction on it. You should only use it if the type of the object is explicitly readable from the line.

So this is allowed:

var person = new Person();

And this is not allowed:

var person = PersonFactory.Create();

And similar for a Linq expression.

Allowed (actually it is required because of the anonymous type):

var person = 
from c in Customers
select new { c.FirstName, c.LastName };

Not allowed:

var person = 
from c in Customers
select Person.Create(c.FirstName, c.LastName);

Otherwise I place no restriction on the use. This way you get maximum readability without comprising that you should always know the type of what you are dealing with. Even when not using intellisense.

At the meeting I mentioned in "The Missing Linq" I asked Anders Hejlsberg why var is not possible on member variables in C#. He told me that they are looking into parallelizing the compiler. And it would be impossible to infer the type across assemblies compiled by different threads of the compiler.

Tuesday, 07 April 2009 09:01:55 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET
# Wednesday, 18 March 2009

What is Linq ? You probably think you know the answer, Linq is after all already quite dated. Well in my experience chances are you only know part of the story. Most of the people I have met have a slight misconception of Linq which limits their use of this great technology.

Let me explain. Linq of course means "Language Integrated Query", we all knew that. This basically refers to the syntactic sugar that Microsoft has poured over the C#3.0 language. I.e the from, where and select keywords and a few more.

In practice Linq is more. It is also a set of Extension methods in a given Linq provider, and a new way of coding, and furthermore many of the C#3.0 features are there to make Linq more useful. Like the var keyword, and lambda expressions.

What I think is limiting the use of Linq is that most people think Linq is a database technology. It is true that Linq can be used for querying databases if you use a Linq provider for a database technology like The LinqToEntities, LinqToSQL or Linq to some other ORM. This is basically Microsoft's "fault", Linq can be used for querying databases, and that is how Linq was promoted, I guess because of the ORM hype.

I was so fortunate to talk to one of the creators of Linq, Anders Hejlsberg in October 2008 when he was giving a lecture in Hilleroed, Denmark. I presented my view to him, that I thought it was a pity that Linq was viewed only as a database technology. He agreed with me, and said that this was because database access was the driving force behind Linq to begin with, and for marketing reasons.

But what is Linq really then ? If you look at an old fashioned SQL query

SELECT SomeColumn FROM SomeTable

You query relational data (SomeTable), and in return you get relational data (A set containing SomeColumn). With Linq you have much more power. You can query anything that implements the IEnumerable<XXX> interface, and you can return one or more .NET objects of any type.

So therefore I think it is much more productive to look at Linq as a means to transform data. In some ways Linq can replace XSLT, I am no XSLT expert but I would guess that you can always write a Linq expression to replace any XSLT transformation, as long as you work in a .NET assembly. Of course an XML document can refer directly to an XSLT transformation, which is not possible with Linq.

Transformations of data are so common in a computer program that we don't even notice them. In fact we use them all the time. And consequently we can use Linq expressions all the time, and should use them most of the time. I would argue that a Linq expression is more readable than "normal" code most of the time. If it is less readable or performs badly you might choose another option.

Here are a few examples of transformations that we don't think of as transformations:

  • Outputting errors to a logfile, or the console, or an eventlog. In this case exceptions are transformed to lines of text.
  • Building a dynamic menu from data in an XML file. In this case the data in the XML file is transformed into menuitems.
  • Building a dynamic Xaml page from some input. The input data is transformed into Xaml.

I will know give you some concrete codefragments to show these types of queries.

Outputting errors

Let's say that you have collected error information in the form of a List of Exceptions. Assume in the following code that ErrorList is a List<Exception>:

(from excep in ErrorList 
where excep is ArgumentException
select excep).ToList()
.ForEach(e => Console.WriteLine(e.Message));

Now you have transformed your Exception data to Visual Data in the Console. In this example only ArgumentException's are printed. Of course you could easily print something better than just the message, e.g ToString() or perhaps a PrettyPrint() extension method for Exception that digs all InnerExceptions out, and prints everything in a nice readable format.

Building a dynamic menu

This example is from my WiiCursor project:

m_ConfigurationMenu = new MenuItem("Configure");
var confMenus =
from configuration in configurations
select Util.GetMenuItem(
configuration.Name,
(sender, args) => Configure((MenuItem)sender, configuration),
configuration.Default);
m_ConfigurationMenu.MenuItems.AddRange(confMenus.ToArray());

In the code shown 'configurations' is a List<WCConfiguration> where WCConfiguration is a class that corresponds to an XML file, and gets initialized by the file. The GetMenuItem(...) method basically "news up" the MenuItem and connects a click eventhandler to it by passing the lambda expression '(sender, args) => Configure((MenuItem)sender, configuration)' to the MenuItems constructor.

So when the user clicks the MenuItem what happens is that the Configure(...) method is called with the MenuItem and most importantly the correct WCConfiguration as parameters.

This might not be the most readable code in the universe. In fact I violate one of my own best practices. Only use the var keyword if the resulting type, here MenuItem, is readable in another way. In the original version I called new MenuItem(...) directly, so that is my (admittedly bad) excuse.

But still the code beautifully illustrates how a Linq expression can Transform the context of XML files to MenuItems that act upon the information in the corresponding file.

Building a dynamic Xaml page

In another project of mine, not yet published, I experiment with logging mouse moves to help me register the time I have used on different projects at the end of the week. A common task for employees around the world. I log the mousemoves in an XML file using a custom format.

<?xml version="1.0" encoding="utf-8"?>
<Activities>
<Activity Name="Activity" Start="10-03-2009 08:01:42" End="10-03-2009 10:01:54" />
<Activity Name="Activity" Start="10-03-2009 12:00:00" End="10-03-2009 16:01:05" />
</Activities>

To make it more appealing visually I transform it to a Xaml file that I load dynamically in a WPF project. The smart thing is that I can do it in a VB.NET assembly combining XML Literals and LinqToXML. Below is the first few lines of the Transformer class that contains the methods to create the Xaml file. Notice how the Xaml can be inlined easily in VB.NET since it is also XML.

Imports System.Linq
Imports System.Linq.Enumerable
Imports System.Xml.Linq
Imports <xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
Imports <xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

Public Class Transformer

    Private Const Column0Width As Integer = 50
    Private Const Column1Width As Integer = 50
    Private Const Column2Width As Integer = 70
    Private Const Column3Width As Integer = 170
    Private Const Column4Width As Integer = 40

    'Converts from a basic XDocument with Activities to a rich one using Xaml.
    'This is done with VB.NET because of the rich LinqToXML experience in VB.
    Public Shared Function ConvertToXaml(ByVal convertFrom As XDocument) As XDocument

        Dim months As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}


        Dim doc As XDocument = New XDocument( _
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Time Statistics" Height="302" Width="514">
    <Grid>
        <TabControl Name="ActivitiesTabControl">
            <%= From month In months _
                Select _
                <TabItem Header=<%= NameOfMonth(month) %> Height="20" Width="80" Selector.IsSelected=<%= SelectMonth(month) %>>
                    <ScrollViewer VerticalScrollBarVisibility="Auto">
                        <Grid>
                            <%= ColumnDefinitions() %>
                            <%= RowDefinitions(NumberOfRows(month, convertFrom)) %>
                            <%= RowHeaders() %>
                            <%= RowsOfMonth(month, convertFrom) %>
                        </Grid>
                    </ScrollViewer>
                </TabItem> %>
        </TabControl>
    </Grid>
</Window> _
                )
        Return doc
    End Function
    ...

XML Literals is the only reason why I sometimes use VB.NET, otherwise I am a C# guy. I would have loved C# to have this nice feature too, my guess is that it was impossible because angel brackets '<' are reserved for generics in C#.

Apart from giving an appealing visual look the code also makes calculations like summing up the time used in an entire day. Linq is ideal for this too.

Summing up

I hope I have convinced you that Linq is more than just a database technology. You knew it already of course, but did you live it and breathe it :O) In my opinion Linq is such an integral part of C#3.0 that there is no avoiding using it all the time.

Wednesday, 18 March 2009 21:49:20 (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.NET | Linq
Archive
<2009 July>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
About the author/Disclaimer
I am a software architect with focus on Microsoft Technologies. I have been working with these in different large companies since 1995. I am currently employed at UVdata A/S.
Here is my View Jesper Niedermann's profile on LinkedIn

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Privacy policy
The privacy policy of this site.

© Copyright 2017
Jesper Niedermann
Sign In
Statistics
Total Posts: 28
This Year: 0
This Month: 0
This Week: 0
Comments: 32
All Content © 2017, Jesper Niedermann
DasBlog theme 'Niedermann' created by Jesper Niedermann, based on 'Business' created by Christoph De Baene (delarou)