Francois Beaussier & Aymeric Gaurat Apelli

Monday

Visual Studio Macro to create a new snippet

Aymeric Gaurat-Apelli: Thanks to François Beaussier for hosting this blog post as my technical blog is no longer available.

Summary

I have written a Visual Studio macro that turns Visual Studio into a Snippet Editor. You simply select the piece of text you want to use in your snippet and the macro will create a snippet that will automatically be loaded by Visual Studio.

Download the latest macro here.

How to use it?

Write the snippet code from within Visual Studio as if you were writing code. Use the syntax $Anything$ to declare Intellisense literals. ($end$ and $selected$ are already used by Visual Studio)


Run the macro from the Macro Explorer:


I suggest you to associate it to a keyboard shortcut, like Alt+S:


The macro will prompt you for the name of the new snippet:


That's it! You can now use your new snippet in Visual Studio.



How to install it?

Open the Macro Explorer by pressing Alt+F8 or through the Tools menu:


In the Macro Explorer, right-click on the Macros node, select "Load Macro Project..." and choose the vsmacros file you downloaded (here)


You should be able to see the "CreateSnippet" macro in the Macro Explorer:


Finally, you will need to edit the macro to fit your environment settings:


Change the author and snippetsPath variables. snippetPaths should be a path that has been added to the Macros Manager (the My Code Snippets folder exists by default)


Save the macro and you are good to go!

Thanks

Big thanks to Patrick Galluci who wrote this article about snippets. My macro is a simple improvement of his great macro.

Thursday

Creating a custom SQL aggregate function in C#

The fact that sql2005 can host the CLR was a big selling point. I kind of always knew that it was possible to extend and create new SQL functions in C# but never really took the time to do it myself.

What do we want to do?

I’d like to be able to create a function that works like the .NET String.Join static method. Here is a sample query that would demonstrate the use our new aggregate function:

select PizzaRecipeId, dbo.strjoin(IngredientName)
from PizzaRecipe
group by PizzaRecipeId

This query would output something like:

1 Cheese, Chicken, BBQ Sauce
2 Cheese, Ham
3 Cheese, Chicken, Pineapple

Let’s do it :)

The first thing is to write the c# code.
Create a new class library project and add a new class called Concatenate. Our new class must:
- have a serializable attribute
- have the SqlUserDefinedAggregate attribute
- implement IBinarySerialize
- have the following 4 methods (there is no interface for them)
o public void Init()
o public void Accumulate(SqlString value)
o public void Merge(Concatenate other)
o public SqlString Terminate()

The implementation itself is straightforward, using a string builder to store the data:

[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize=8000)]
public class Concatenate : IBinarySerialize
{
private StringBuilder sb;

public void Init()
{
sb = new StringBuilder();
}

public void Accumulate(SqlString value)
{
if (sb.Length != 0)
{
sb.Append(", ");
}

sb.Append(value);
}

public void Merge(Concatenate other)
{
sb.Append(other.sb);
}

public SqlString Terminate()
{
return new SqlString(sb.ToString());
}

#region IBinarySerialize Members

public void Read(BinaryReader r)
{
sb = new StringBuilder(r.ReadString());
}

public void Write(BinaryWriter w)
{
w.Write(sb.ToString());
}

#endregion
}

If the project compiles, let’s continue with the commands that will actually load the dll into sql server and reference the aggregate function:

create assembly clr_integration from 'C:\dev\learning\sql2005\ \clr_integration\bin\debug\clr_integration.dll' with permission_set = safe
GO

create aggregate strjoin(@input nvarchar(200)) returns nvarchar(max)
external name clr_integration.Concatenate

The permission_set is safe because the assembly does not perform any interop or contains any unsafe blocks.

Let’s create a table and some dummy data:


if (object_id('PizzaRecipe') is not null) drop table PizzaRecipe
create table PizzaRecipe
(
PizzaRecipeId int NOT NULL,
IngredientName nvarchar(200)
)

insert PizzaRecipe values(1, 'Cheese')
insert PizzaRecipe values(1, 'Chicken')
insert PizzaRecipe values(1, 'BBQ Sauce')
insert PizzaRecipe values(2, 'Cheese')
insert PizzaRecipe values(2, 'Ham')
insert PizzaRecipe values(3, 'Cheese')
insert PizzaRecipe values(3, 'Chicken')
insert PizzaRecipe values(3, 'Pinnaple')

Everything should now be ready and it’s time to test it :)

Writing the aggregate function was actually simpler than what I imagined. It’s now just a matter of detecting when this type of feature can be used.

TFS: removing _svn folders

I recently had the need to clean up a project in TFS. When it was imported, little care had been put in making sure that only the required files would be on source control.

The most noticable folders that were to be removed from TFS were: '_svn', 'bin' and 'obj'.

As I'm not a big fan of doing things manually (yes, even if doing it manualy is faster - well in that case it was probably faster to write the script) I ended up trying to remember how to do those fancy FOR loops in DOS :)

First, build a list all the folders (or files) you want to remove:

dir /s /b _svn bin obj > files_to_delete

Creating that file is handy and you can edit it before running the following query:

for /f "delims=" %g in (files_to_delete.txt) do tf.exe delete "%g" /login:DOMAIN\login,password

note: make sure that tf.exe is in your path, or replace it with the full path.

you can now refresh your pending checkin in visual studio and check it in !

Tuesday

The cost of an exception is about 6ms !

I have read quite a few times that exceptions were slow. I came to wonder about how slow they actually were? Is that big enough to care about it ? After all, hardware is pretty fast nowdays, isn't it?

Well it turns out that throwing and catching an exception takes about 6ms on my machine (Core Duo, 2ghz)

I you want to know why it takes 6ms, have a look at this fantastic post :)

Now, a few milliseconds, it does not look like a long time, but think about a web server, handling hundreds of requests at the same time. If each request uses a few Int.Parse that fails(or whatever code that may throw exceptions) , that could end up being quite significant.

This is a simplified version of the code I used (removed the loop to get an average value):

private void Execute()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();

    ThrowAndCatchException();

    sw.Stop();

    Console.WriteLine("Time taken: {0}ms", sw.ElapsedMilliseconds);
}

private void ThrowAndCatchException()
{
    try
    {
        throw new Exception();
    }
    catch (Exception) { }
    {
    }
}

Monday

Visual Studio has also an hexadecimal editor !

Have you ever wondered if visual studio can hex edit files ? Well it's actually possible but not very intuitive...

Go to File -> Open -> file
Select the file that you want to open, the Open button state will change to enable
Click the small drop down list at the right of the Open button and select Open With

You will get a list of additional editors, choose Binary Editor :)

Wednesday

Saving TFS queries to a file

This morning I wanted to share TFS queries that I created in the "My Queries" folder with a team mate. I found that the best way of doing that was to save them as files (.wiq), send them by email and he just had to open them and adding them to his "My Queries" folder.

How to save a query to a file:

1) Right click on the query, select view query.
2) Go to "File" -> "Save QueryName As"
3) Select File

This will create a QueryName.wiq file.

How to add a .wiq file to your "My Queries" folder ?

1) Double click on the .wiq file
2) Go to "File" -> "Save QueryName As"
3) Select "My Query (only visible to me)"

Enjoy :)

Friday

Sydney’s Microsoft Ready Summit 2006

I attended the Sydney’s Microsoft Ready Summit today. It was a nice event in the Darling Harbour convention centre, targeted to developers, IT professionals and IT decision makers. The developer sessions were about the new Windows Vista user experience and Office 2007.

I took a few notes about the things I thought were worth remembering. I hope that I will interest some people that did not make it to the event.

The developer keynote was presented by Andrew Coates who is a Microsoft evangelist and most of the other sessions were presented one of my Readify co worker: Mitch Denny.
We started with the Expression Interactive Designer. This is a lot like the Macromedia Flash editor, but Expression will generate XAML files. This new format (at the heart of WPF) should be the common language talked by both developers and interface designers (i.e. the same XAML file can also be opened in Visual Studio). It will hopefully reduce the number of cases where developers have to integrate a full screen bitmap, tiled into 200 tiny pieces J

A short look at PeerNet was the occasion to try finding legal uses of the P2P technology. Vista provides a new communication stack, what can we do with it ? A few examples were discussed : a collaborative meeting where an ad hoc network can be created using auto discovery features, a data synchronisation scenario where a Readify ultra mobile worker would keep all his devices up to date in an efficient way.

The search API was briefly overviewed by talking about the “New York Times reader” that integrates with the Vista search engine.

A humoristic history of icons (starting with the plain old 255 colours win95 style) introduced the “on the fly” generation of the high resolution Vista icons. It’s possible to write a custom preview handler for your own file format. No doubts that end users will quickly expect to be able to view something relevant about the files they are browsing within the Explorer window.

We had a look at the gadgets that can be added to the vista sidebar. They can be created in either HTML or in WPF. Gadget files are in fact just zip files. Anyone can rename a gadget and have a look at it. If you want to create one, it’ll probably be easier to start by modifying another one that does something similar. That’s a good way to learn how they work.

What would Vista be without the wonderful glass feature? Well first, it seems that whole point of the glass effect, beyond the fact that it’s nice looking, is that you get to focus to the important stuff inside the window. We had a look at how to use glass effect in your own application, using winforms or WPF. In both cases, a reference to an unmanaged API is required. Search for DwmExtendFramIntoClientArea and DwmApi.dll for examples. Warning: don’t misuse that functionality! We do not want to see new application using the glass effect everywhere; it would defeat the whole purpose J

A lot of effort has been put into redesigning the standard dialog windows. They are a lot simpler, with most options hidden from the user. The idea is that the dialogs now focus on what’s important. For example, the new open file dialog has got very few options displayed by default. The basic action performed by the dialog is to give a name to the file. Selecting a folder is not the primary concern anymore because the application would have probably set the current path to some meaningful folder and that anyway with the new search and filtering features of vista, saving all the documents in one single place should not be an issue anymore. All the new standard dialogs can as usal be extended (and it is even supposed to be easier than what it used to be). Search for the following keywords if you are interested: IFileDialog, IFileOpenDialog.

Last but not least, the new xml Office file format. The big change is that xml is now the default format when working with Office 2007 documents. Once again the files are just zip archives. You can rename your .docx to .zip and start to have a look inside by yourself. That’s pretty cool! Pictures are stored in their binary format for efficiency reason (base64 would make it 1.33 times bigger). It’s quite cool to be able to play directly with the list of images inside a PowerPoint document. You can manipulate the xml yourself or you can use a set of new dotnet classes (search for System.IO.Packaging). As far as compatibly is concerned, patches that can open/edit/save the new xml formats are already available for the previous versions (up to office 2000). There was a good question: what about password protected documents? The answer is that it is handled automatically by the zip format which supports encryption on a file by file basis.

Wednesday

Where is that azman dll ? :)

When using azman, it's better to reference the following dll, rathing than browsing in the list of registred COM components. You'll get a much more friendly namespace.

Azman reference path:

C:\WINDOWS\Microsoft.NET\AuthMan\1.2\microsoft.interop.security.azroles.dll

Should I use Page_Init or OnInit ?

I came across an interesting issue last friday.

There was an empty Page_Init method in some web control. I removed it, thinking that it would not do any harm.

Well, in fact, it was actually hidding the base class Page_Init method which used not to be executed. Of course, after my change, the base method was called and that caused a crash in the application :)

What I have learned from that:

When creating a base class that requires initialization, it's better to use the OnInit method, rather that the Page_Init.

When using OnInit, the derived class will have to explicitly use the override keyword, which may help other developers avoiding this kind of issues.

How can I get...

... the sid for the current user:

use WindowsIdentity.GetCurrent().Owner.Value

... the token for the current user:

use WindowsIdentity.GetCurrent().Token