CopySourceAsHtml Add-In with Visual Studio 2008

Tags: , ,
No Comments »

CopySourceAsHtml (CSAH) is a small and nice add-in for Visual Studio 2005 to copy the selected source code html-formatted to the clipboard. This is very useful if you want to paste this code into your blog (as I do here sometimes).

Unfortunately the current version 2.0.0 does not work with Visual Studio 2008 out of the box, but it is very simple to get it running.

The add-ins are located in below documents-folder in a path like this: C:\Users \Benjamin \Documents \Visual Studio 2005 \Addins. Just copy all files beginning with CopySourceAsHtml*.* to the corresponding folder for Visual Studio 2008: C:\Users \Benjamin \Documents\ Visual Studio 2008 \Addins.

Now you have to edit the CopySourceAsHtml.AddIn file with a text editor: only change at two positions in this short xml-file the Version value from 8.0 to 9.0.

After a restart of Visual Studio 2008 you should find the CopySourceAsHtml add-in in the Tools / Add-in menu and of cause in the context menu of the code editor.

First steps on aspect oriented programming

Tags: , , ,
No Comments »

Since I saw the first implementation of aspect oriented programming (AOP) frameworks for java I became a fan of AOP but it took a long time till now before I could start using AOP in my projects. The main reason was that simply no good and easy to use AOP framework for .net existed. There was one research project but you weren’t allowed to use their utilities in project other then research projects.
But a few weeks ago I discovered PostSharp and it is really great and very simple. If you have no idea what’s all about AOP you should read the Wikipedia article or the start page of the PostSharp project. There you find a short example showing the usage of an aspect in C# code.
I also want to show you my first experience with some aspect oriented programming.

First: the problem I want to address
I sounds very simple: I’ve got a base-class and some sub-classes. All provide a method GetName(). All sub-classes within the same type should return the same name that is given at compile time. It’s just a const string for each class. The following code addresses these needs in a straight forward way:

class BaseClass

{

    public virtual string GetName()

    {

        return “-“;

    }

}

 

class ClassA : BaseClass

{

    public override string GetName()

    {

        return “A”;

    }

}

 

class ClassB : BaseClass

{

    public override string GetName()

    {

        return “b”;

    }

}

Second: what I don’t like with this solution
This seems good, but I’ve got some more special needs. All classes are generated by the DSL Tools that means they contain much other code and no line written by me. In my use case these classes are shape-objects.
Thanks to the partial keyword in C# I could extend every class within its own .cs-file, but I didn’t like this. It would mean I have to create many additional .cs-files only for providing a single string to the class. But all other definition is stored in the DSL-model described by the DSL Tools and some part of the shape declaration is located in the .cs-files.
In the DSL-model I can provide each class with a custom attribute, so I’m looking for a solution with no additional code in the sub-classes besides a custom attribute.
With the use of reflection it could be the following:

class NameTextAttribute : Attribute

{

    public NameTextAttribute(string name)

    {

        this.Name = name;

    }

 

    public string Name { get; set; }

}

 

class BaseClass

{

    private string name = null;

 

    public virtual string GetName()

    {

        if (name == null)

        {

            object[] a = this.GetType().GetCustomAttributes(

                            typeof(NameTextAttribute),

                            true);

 

            if (a.Length > 0)

                name = ((NameTextAttribute)a[0]).Name;

            else

                name = “-“;

        }

 

        return name;

    }

}

 

[NameTextAttribute(“A”)]

class ClassA : BaseClass {}

 

[NameTextAttribute(“b”)]

class ClassB : BaseClass {}

This is working and as you see, no additional code is needed in the sub-classes. But nevertheless I would like to avoid using reflection. Reflection seems to me inappropriate in this case.

Third: Using AOP
The idea of AOP is to add code to the class that you can write in another position, in the aspect. The aspect weaver (in my case the PostSharp Laos library) adds this code on compiletime (not runtime!) to the class.
My strategy is to add some code after the constructor execution that will initialize the name-property:

class BaseClass

{

    public virtual string Name { get; internal set; }

 

    public virtual string GetName()

    {

        return this.Name;

    }

}

 

[NameAspect(“a”)]

class ClassA : BaseClass

{

    public void someMethodInA()   { }

}

 

[NameAspect(“b”)]

class ClassB : BaseClass {}

 

[Serializable]

class NameAspect : OnMethodBoundaryAspect

{

    private string name = “-“;

    public NameAspect(string name)

    {

        this.name = name;

    }

 

    override bool CompileTimeValidate(MethodBase m)

    {

        return m.IsConstructor;

    }

 

    override void OnSuccess(MethodExecutionEventArgs args)

    {

        BaseClass obj = args.Instance as BaseClass;

        if (obj != null)

            obj.Name = name;

    }

}

The base-class now provides a property name (declared with the new C# 3.0 syntax) and the GetName() method returning the property value. As in the last example the sub-classes have the attribute declared and contain no other code.
The magic happens in the attribute (or, if you like, somewhere in the PostSharp.dll). It is derived from OnMethodBoundaryAspect, an aspect base type where I can add code to a method in another class before and after the method call and on exception and on success of the method call.
My constructor of this aspect gets only the name string and stores it in a variable.
The code that should be executed every time a constructor of a class with this aspect is calls can be find in the OnSuccess()-method. Here only the property of the BaseClass will be set.
With the CompileTimeValidate()-method I can specify at compiletime for witch methods the code should be injected. For my needs this is only the constructor. All other methods of my class will not be changes by this aspect.

Fourth: behind the scene
With adding the PostSharp references to my project the PostSharp postcompiler is called automatically after compiling my assembly and the code is added. If you take a look with the Reflector you will see the following:

class ClassA : BaseClass

{

    static ClassA()

    {

        if (!~PostSharp~Laos~Implementation.initialized)

            LaosNotInitializedException.Throw();

        ~PostSharp~Laos~Implementation.~targetMethod~3 =

                methodof(ClassA..ctor);

        ~PostSharp~Laos~Implementation.NameAspect~3.RuntimeInitialize

                (~PostSharp~Laos~Implementation.~targetMethod~3);

    }

 

    public ClassA()

    {

        MethodExecutionEventArgs ~laosEventArgs~1;

        try

        {

            ~laosEventArgs~1 = new MethodExecutionEventArgs(

                    methodof(ClassA..ctor, ClassA), this, null);

            ~PostSharp~Laos~Implementation.NameAspect~3.OnEntry(~laosEventArgs~1);

            if (~laosEventArgs~1.FlowBehavior != FlowBehavior.Return)

                ~PostSharp~Laos~Implementation.NameAspect~3.OnSuccess(~laosEventArgs~1);

        }

        catch (Exception ~exception~0)

        {

            ~laosEventArgs~1.Exception = ~exception~0;

            ~PostSharp~Laos~Implementation.NameAspect~3.OnException(~laosEventArgs~1);

            switch (~laosEventArgs~1.FlowBehavior)

            {

                case FlowBehavior.Continue:

                case FlowBehavior.Return:

                    return;

            }

            throw;

        }

        finally

        {

            ~PostSharp~Laos~Implementation.NameAspect~3.OnExit(~laosEventArgs~1);

        }

    }

 

    public void someMethodInA() {}

}

I really don’t know what’s that all about but I can see that there is code added only to the constructor, someMethed() is empty as in my given source code.

In the next weeks I will try to cover more examples and solutions with PostSharp and AOP.

Setup Microsoft Help Explorer (Visual Studio Combined Help Collection)

Tags: ,
1 Comment »

As we all know, the main resource for help on Visual Studio and .net is the Microsoft Help Explorer that is installed with Visual Studio. Sometimes it is called the Visual Studio Combined Help Collection. Most of the Microsoft development tools (for example SDKs for Office and Visual Studio) but also tools from other vendors install their help resources into this Explorer.
It is really nice if it works. But on my system I ended up with not only one central Help Explorer but with three, each containing different content. One came with Visual Studio 2005, one with Orcas and another with the Visual Studio SDK. For some reason only the last one showed up the .net-framework help, but every time I pressed F1 in Studio the first one – without the content – opened.
I knew that there is somewhere a settings dialog where you can see the installed content of the Explorer and enable or disable some of it. But Microsoft does a very good job in hiding this dialog. It is shown like any page of the help. To find it just go to the Index and look for “Visual Studio 2005 Combined Help Collection Manager” or for Orcas Beta 2 “…2007…” – I think they will change the name in the final Visual Studio 2008.

msi-Installer created with Visual Studio and the RemovePreviousVersions-Option

Tags: , ,
1 Comment »

[Edit: this seems to be solved in Visual Studio 2008. See this article]

In theory if you create a setup project within Visual Studio, you can set the RemovePreviousVersions to force the created setup to uninstall all previous versions of the same software already install on the target computer. This is a very useful option, but it does not work under all circumstances. But before I go into the problems a brief overview how it should work:

Besides the RemovePreviousVersions flag there are two further properties: UpgradeCode and ProductCode. The UpgradeCode must be the same for all setup projects (that is for the old versions and for the new version). The installer uses this UpgradeCode to detect an older version of the software. The ProductCode must be different for every version, this is uses by the installer to detect different versions of the same software . If you change the Version of an installer Visual Studio creates a new ProductCode.

This works the way described here in the same way described in the product documentation as long as you do not use a Version number below 1.0. If you name your beta and prerelease version something like 0.5 the installer does not recognize an previous version and will not uninstall it, but installs the new version side by side which can be a problem for you installation e.g. if it will be installed in the same directory.

Unfortunately this seem to be a known issue since 2004 or earlier and is not fixed in Visual Studio 2005. The installer looks only for previous Versions greater or equal 1.0 but not for versions less than 1.0.

But there is a workaround. You have to patch the MinVersion in the created msi-file with a tool called orca.exe.

  1. Download the Windows Platform SDK – about 400 MB
  2. Install it – Full install is about 1 GB but you only need the MSI-SDK parts, so choose the custom installation.
  3. In the directory of the SDK you will find an orca.msi – install it
  4. Start the orca.exe and open your created msi
  5. Got the Upgrade-Table
  6. Look for the 1.0.0.0 in the VersionMin-field and change it to somethink like 0.1.0.0
  7. Save the changes to the msi

Windows shell32.dll SHFileOperation marshalling and hNameMappings

Tags:
2 Comments »

For my Software PhotoTagStudio I implemented a new feature to copy jpg-files from a memory card to the disk. I wanted to use that fancy Windows XP explorer copy dialog with the papers flying from one folder to another. And where I get the (more or less accurate) time estimation for free.

Searching the web I found the shell32.dll and the SHFileOperation function. This function does exactly what I need and on www.codeproject.com you can find a great article by arikp on how to address system32.dll from .net. arikp included sourcecode so you find everything you need to call the system32.dll functions from .net. Unfortunately two little features didn’t not work as expected:

hNameMappings is rarely used and can help only if I’m interesting in the new names the user had to give during the operation…

(but did not work in the ShellApi.cs)

…and finally lpszProgressTitle, If we set the flag FOF_SIMPLEPROGRESS, the progress dialog box does not present the file names and is supposed to present the text of this parameter. When I test this function I couldn’t get this parameter to show, it didn’t show the file names with the SIMPLEPROGRESS flag but it did not show the title parameter. What can I say, strange.

(did not work as well)

But I have to know the new names and thus had to get the NameMappings-thing working all by myself (I could not find a solution anywhere in the web). So I asked a good friend of mine, Wolfram Bernhardt, who subsequently did most of the following work:

He found a problem in the SHFILEOPSTRUCT:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHFILEOPSTRUCT
{
    public IntPtr hwnd;
    public UInt32 wFunc;
    public IntPtr pFrom;
    public IntPtr pTo;
    public UInt16 fFlags;
    public Int32 fAnyOperationsAborted;
    public IntPtr hNameMappings;
    [MarshalAs(UnmanagedType.LPWStr)]
    public String lpszProgressTitle;
}

When marshalling this from .net to unsafe/native each element of the struct is stored at an address that is an multiple of 4. (This is the default for .net on Win32 for performance reasons). This leads to some unused bytes – i.e. fFlags is only 16 bit width and the next parameter should not leave a space of two byte.

The functions of shell32.dll are old fashion and do not waste any space. So they read wrong values after fFlags. The fAnyOperationsAborted wasn’t harmed that much and it’s value wasn’t checked too carefully in my application. But the hNameMappings-Pointer went totally wrong.

To change this behaviour you just have to add the Pack=2 parameter to the attribute:
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

After this little change hNameMappings is marshalled back correctly and points to a mapping-structue. As a “side-effect” the lpszProgressTitle is now shown as expected – at least on Win XP, Vista seems to ignore this string. Obviously MS has changed this function of shell32.dll. But the more important functions work as desired.

To get the new filenames you have to set the Flags FOF_WANTMAPPINGHANDLE and FOF_RENAMEONCOLLISION. The latter allows the function to (automatically) rename files during copying. If a filename already exists, the new copy is renamed to something like “Copy of [filename]”. On a Windows Vista machine you don’t need the FOF_RENAMEONCOLLISION flag, because the user can choose the new option “Keep both the original file and the copyâ€? in the dialog that asks to override existing files. In both cases the hNameMappings is filled with a pointer to a list of Mapping objects that contain the original and the new filenames.

To get the list from the hNameMappings Pointer you have to implement two more structs and Wolfram did it, too. He added a new property NameMappings to the ShellFileOperation Class. (For details see the source code of the changes ShellLib.)

With the following download we provide an updated Version of the ShellLib with the described changes. For more information please refer to the original article on The Code Project and take a look on the demo code over there.

The enhanced ShellLib Code

Microsoft .net framework 2.0 treeview bug

Tags:
No Comments »

Under some circumstances the windows forms treeview control of the new microsoft .net framework 2.0 does not display the last node!

A very simple example can demonstrate this behavior on windows xp professional with service pack 2 (maybe on other platforms, too). Create a windows application with a treeview and a button on it. Set the anchor of the treeview to all sides and add the following code:

private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 25; i++) this.treeView1.Nodes.Add(i + " xxxxxxxxxxxxxxxxxxxxxxxxx"); } private void button1_Click(object sender, EventArgs e) { this.treeView1.Nodes[24].EnsureVisible(); }

When you start this application and scroll down to the end of the treeview you can see this picture:
2006-01-24a.png
The node with the number 24 is missing but the lines of the tree shows that there is another node after 23.

If you resize the form parts of the missing note becomes visible but at the moment it could be full visible it will be hidden again.
2006-01-24b.png
2006-01-24c.png
2006-01-24d.png

The EnsureVisible-method of the last node does work neither.

I found a workaround. Just remove the Application.EnableVisualStyles() line in the main() function. Without visual styles enabled it works fine. But I want to use these styles...

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in