# 29 Ocak 2007 Pazartesi
It sometimes get frustrating when you debug your project through another instance of Visual Studio, especially if you manipulate the "active" DTE within your debug project. I somehow ended up to the following when getting a reference to DTE:


It worked most of the time, but "not all the time" means you may add a project to the solution where your code resides (the parent VS instance), rather than where the debugging session is. So, after some research, DTE code turned into this:


public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);


public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);


public static DTE GetDTE(string processID)


    IRunningObjectTable prot;

    IEnumMoniker pMonkEnum;


    string progID = "!VisualStudio.DTE.8.0:" + processID;


    GetRunningObjectTable(0, out prot);

    prot.EnumRunning(out pMonkEnum);



    IntPtr fetched = IntPtr.Zero;

    IMoniker[] pmon = new IMoniker[1];

    while (pMonkEnum.Next(1, pmon, fetched) == 0)


        IBindCtx pCtx;

        CreateBindCtx(0, out pCtx);

        string str;

        pmon[0].GetDisplayName(pCtx, null, out str);

        if (str == progID)


            object objReturnObject;

            prot.GetObject(pmon[0], out objReturnObject);

            DTE ide = (DTE)objReturnObject;

            return ide;




    return null;


posted on 29 Ocak 2007 Pazartesi 22:17:43 UTC  #   
I was trying to solve the Custom Tool property issue with .actiw files in ActiveWriter, as suggested by Bogdan Pietroiu months ago, and spent a clear hour trying to figure how to inject my own registry keys into WiX setup project of DSL Tools. I modified the .vstemplate for .actiw files to include the following:



  <CustomParameter Name="$itemproperties$" Value="CustomTool" />

  <CustomParameter Name="$CustomTool$" Value="ActiveWriterCodeGenerator" />



and thought that the file, when added to the project, will have Custom Tool property already set. I was appearently wrong (documentation says it should work).

Bogdan's suggestion was to have a key named after the file extension under Generators\{Language}, and I manually confirmed that it works great. So, how to automate the process of adding this reg key through the setup? WiX Toolkit documentation shows the way, so I copied Registry.wxs to have my own key registered.

<?xml version="1.0" encoding="utf-8"?>

<Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'>

  <Fragment Id="CustomToolFragment">

    <FeatureRef Id="DefaultFeature">

      <ComponentRef Id="_ActiveWriterCTReg" />


    <DirectoryRef Id="TARGETDIR">

      <Component Id="_ActiveWriterCTReg" Guid="{some GUID}">

        <Registry Root='HKLM' Key='Software\Microsoft\VisualStudio\8.0\Generators\{164b10b9-b200-11d0-8c61-00a0c91e29d5}\.actiw' Id='{some GUID}' Type='string' Value='ActiveWriterCodeGenerator' />

        <Registry Root='HKLM' Key='Software\Microsoft\VisualStudio\8.0\Generators\{fae04ec1-301f-11d3-bf4b-00c04f79efbc}\.actiw' Id='{some GUID}' Type='string' Value='ActiveWriterCodeGenerator' />





<Registry> elements define the key to be added, as you may have guessed. Anyway, although I changed the build action on the .wxs and although it seems that Candle and Light picked up the file, the installer didn't add the registry key. So? Orca to the rescue. You should check Component and Registry tables in .msi file to check if your key slipped in, and Orca shows them quite detailed. In my case, though, it shows the absence of my additions.

Long story (not so) short, it seems that I should examine Registry.tt as the first step, but didn't. To include your ComponentRef in DefaultFeature, you should have your Fragment as FragmentRef in Main.wxs . So, you should add each of your custom fragment in the list defined in customFragmentIds in InstallerDefinitions.dslsetup as shown below:

<installerDefinition xmlns="http://schemas.microsoft.com/VisualStudio/2005/DslTools/InstallerDefinitionModel"



I hope this info helps someone.

posted on 29 Ocak 2007 Pazartesi 21:13:31 UTC  #   
# 08 Aralık 2006 Cuma

At work, I'm devoting a fair amount of my time to SQL BI concepts lately. One of the exciting concepts (there are many, believe me) of SSAS on SQL 2005 is Key Performance Indicators. A KPI is the creme de la creme of all the data aggregations. It's the final display of knowledge extracted from the vast amount of data to answer questions like "Based on such and such criteria, are we profitable?".

Since KPIs are mostly for non-techies, it's best to display them in a dashboard like scenario, where SharePoint is a good example. A handy newcomer in dashboard scene is Vista Sidebar, and displaying KPI data on the Sidebar was the most logical exercise for Sidebar development for me with the release of Vista:

Without perfecting that, WPF/E came out and I wondered if I can display KPIs in a Sidebar gadget using WPF/E. Result? I CAN'T. I don't know if it's the security settings or is it the WPF'E engine's fault but, the javascript method in Loaded event does not get called for a .xaml file if it's run in a Sidebar.

<Canvas xmlns="http://schemas.microsoft.com/client/2007"
  <Canvas x:Name="kpiCanvas" />

Here's the code for the WPF/E thing (gadget? applet? app?). Note that, everything's fine in IE:
KPIDS.rar (7.21 KB)

  • WPF/E currently doesn't like .gif images in IMAGE tags. <Image Source="star.png" /> is fine but  <Image Source="star.gif" /> fails without an error, or it's the case for me.
  • I lost (accidentally overriden) the source for KPI sidebar gadget (the one without WPF/E, two images above) but you can easily build one from the given source. Change "createKPI" in kpiLibrary.js to render to html instead of xaml.
  • createFromXaml is a nice method but, we'll have programmatic access to the object model won't we?
  • Although the current form of WPF/E is nice, I won't touch another CTP of it untill I can code in C# against it. JavaScript is sooooo boooring.
  • Follow the steps below to setup remote XMLA access to SSAS through web services. It's required to access KPI data remotely:
    Configuring HTTP Access to SQL Server 2005 Analysis Services on Microsoft Windows Server 2003.
posted on 08 Aralık 2006 Cuma 23:00:36 UTC  #   
# 01 Kasım 2006 Çarşamba
Go visit www.castleproject.org and get the lates bits.

The amount of information there is increadible, MonoRail getting started docs are extremely helpful for me. After seeing "Getting Started with ActiveRecord" topic, you will have no excuse not to use ActiveRecord in your next project. And API documentation is just what I need for ActiveWriter's properties window documentation :)

The question is, will I manage to release something new with ActiveWriter to celebrate the Castle release and the hard work these guys doing? Let's see:

Although implementing the toolwindow above turned out to be harder than I thought, I was actually referring to generics support in ActiveWriter, which is still waiting my attention. So, I'll try to hurry++ and sleep--;
posted on 01 Kasım 2006 Çarşamba 19:58:57 UTC  #   
# 11 Ekim 2006 Çarşamba
I can't dechiper legal documents even in Turkish, how can I decide if I'm allowed to release the source code or not by looking at the VS DSK license? If Microsoft has a department or something to ask "would you get angry if I release this?", I want to know.

Anyway, you can download the source of ActiveWriter Preview here. I have removed some .tt files copyrighted by Microsoft, but instructions are available in the download to add them from an empty DSL Tools project. Lack of .tt files will prevent any "just extract and open" scenario, sorry about that.

Back to the license adventure. I have asked in DSL Tools forum if it's possible to release the source, and directed to the SDK license. Then I found a post on Interop blog, saying that "It is possible to release extensions to Visual Studio under open source licenses" with an IANAL notice. I have convinced that I can, until I notice copyright notes on all over the .tt files, which are very much the core of the code generation on DSL Tools part. So I followed the next best approach, removed copyrighted stuff.

Having copyright notices in .tt files, for Microsoft, is a bit silly, by the way. They don't include notices in AssemblyInfo or config files (or any other template generated solution files), what's different with .tt's?


Gareth Jones from DSL Tools team replied, saying that .tt files are considered to be samples and developers may customize them with whatever license statements they have. This is extremely good. I'll re-release the source with all the .tt files included.

And for those who don't know what a .tt file is for; they are input files for the text templating engine of DSL Tools. They have ASP.NET like <# #> syntax to generate output as VS solution files. Very handy, but I prefered a more classic approach in ActiveWriter. CodeGenerationHelper is much nicer in plain C# than .tt syntax.

ActiveWriterReport.tt file:

<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" debug="true"#>
<#@ output extension=".%EXT%" #>
<#@ ActiveWriter processor="ActiveWriterDirectiveProcessor" requires="fileName='%MODELFILE%'" #>
<#@ import namespace="Altinoren.ActiveWriter.CodeGeneration" #>
    CodeGenerationHelper helper = new CodeGenerationHelper(this.Model, "%NAMESPACE%");

and the usage:

protected override byte[] GenerateCode(string inputFileName, string inputFileContent)


    ResourceManager manager =

        new ResourceManager("Altinoren.ActiveWriter.VSPackage",

                            typeof (ActiveWriterTemplatedCodeGenerator).Assembly);

    FileInfo fi = new FileInfo(inputFileName);

    inputFileContent =

        manager.GetObject("ActiveWriterReport").ToString().Replace("%MODELFILE%", fi.Name).Replace(

            "%NAMESPACE%", FileNameSpace).Replace("%EXT%", "cs"); // TODO: Get file extension from the project model


    byte[] data = base.GenerateCode(inputFileName, inputFileContent);

    return data;


posted on 11 Ekim 2006 Çarşamba 09:59:00 UTC  #   
# 30 Eylül 2006 Cumartesi

Help and download available here.

If you missed the announcement, it is a visual designer, an addin for Visual Studio 2005, to design a domain model and to generate code decorated with ActiveRecord attributes.

Please send bugs, suggestions and feature request through the Navigation pane of the site.

Thanks To

ActiveRecord team for the great and well supported library, NHibernate and Hibernate community for making this chain-reaction possible, Microsoft DSL Tools team for making DSL modelling this easy, everyone at DSL Tools forum, and my wife Damla for her patience.

Pluralization code is simplified version of Damian Conway's algorithm in paper An Algorithmic Approach to English Pluralization
Server Explorer integration greatly inspired from Ted Glaza's post here.
posted on 30 Eylül 2006 Cumartesi 18:12:03 UTC  #   
# 15 Eylül 2006 Cuma

Head to the VSIP member site to download. I'm %46 done right now.

Since DSL Tools v1 is bundled with this final release, and since I'll finally be able to include redistributables with ActiveWriter installer, I'm twice excited right now :)

My plan is:

    Compile ActiveWriter against DSL Tools v1
    Fix things broken by the v1
    Add one2one support (Just manual modelling. No heuristics for drag-drop. Will complete that later)
    Test & release.

 And about the current state of the project:

    Handles many-to-one, both in manual design and drag-drop.
    Handles many-to-many, both in manual design and drag-drop.
    Primary keys, properties, fields.
    Composite keys: Writes the attribute as well as a separate composite key class :) Yup.
    Some more model validators (If PrimaryKeyType.Sequence, then sequence name should be defined etc.)
    Versions and Timestamps.
posted on 15 Eylül 2006 Cuma 12:31:35 UTC  #   
# 28 Ağustos 2006 Pazartesi
I use CodeDom to generate ActiveRecord classes in ActiveWriter. Quite fancy, but gets complicated easily. To generate something like this:

        public override bool Equals(object obj)


            if (obj == this) return true;

            if (obj == null || obj.GetType() != this.GetType()) return false;

            MyCompositeKey test = (MyCompositeKey)obj;

            return (_keyA == test.KeyA || (_keyA != null && _keyA.Equals(test.KeyA))) &&

              (_keyB == test.KeyB || (_keyB != null && _keyB.Equals(test.KeyB)));


you code this:

        private CodeTypeMember GetCompositeClassEqualsMethod(string className,  List<CodeMemberField> fields)


            CodeMemberMethod equals = new CodeMemberMethod();

            equals.Attributes = MemberAttributes.Public | MemberAttributes.Override;

            equals.ReturnType = new CodeTypeReference(typeof(Boolean));

            equals.Name = "Equals";


            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(typeof(Object), "obj");



            equals.Statements.Add(new CodeConditionStatement(

                                      new CodeBinaryOperatorExpression(

                                          new CodeFieldReferenceExpression(null, "obj"),

                                          CodeBinaryOperatorType.ValueEquality, new CodeThisReferenceExpression()

                                          ), new CodeMethodReturnStatement(new CodePrimitiveExpression(true))




            equals.Statements.Add(new CodeConditionStatement


                                      new CodeBinaryOperatorExpression


                                          new CodeBinaryOperatorExpression(

                                              new CodeFieldReferenceExpression(null, "obj"),

                                              CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(null)),


                                          new CodeBinaryOperatorExpression(

                                              new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(null, "obj"), "GetType"),


                                              new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "GetType"))


                                      , new CodeMethodReturnStatement(new CodePrimitiveExpression(false))





                new CodeVariableDeclarationStatement(new CodeTypeReference(className), "test",

                                                    new CodeCastExpression(new CodeTypeReference(className),

                                                                            new CodeFieldReferenceExpression(null, "obj"))));


            List<CodeExpression> expressions = new List<CodeExpression>();

            foreach (CodeMemberField field in fields)



                    new CodeBinaryOperatorExpression(

                        //_keyA == test.KeyA

                        new CodeBinaryOperatorExpression(

                            new CodeFieldReferenceExpression(null, field.Name),


                            new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(null, "test"), field.Name)),

                        CodeBinaryOperatorType.BooleanOr, // ||

                        new CodeBinaryOperatorExpression(

                            //_keyA != null

                            new CodeBinaryOperatorExpression(

                                new CodeFieldReferenceExpression(null, field.Name),


                                new CodePrimitiveExpression(null)


                            CodeBinaryOperatorType.BooleanAnd, // &&

                            // _keyA.Equals( test.KeyA )  

                            new CodeMethodInvokeExpression(

                                new CodeFieldReferenceExpression(null, field.Name), "Equals",

                                new CodeFieldReferenceExpression(

                                    new CodeFieldReferenceExpression(null, "test"), field.Name))






            CodeExpression expression = null;

            if (expressions.Count > 2)

                expression =

                    new CodeBinaryOperatorExpression(expressions[0], CodeBinaryOperatorType.BooleanAnd, GetBooleanAnd(expressions, 1));


                expression = new CodeBinaryOperatorExpression(expressions[0], CodeBinaryOperatorType.BooleanAnd, expressions[1]);



            equals.Statements.Add(new CodeMethodReturnStatement(expression));


            return equals;


Strangely, there's no CodeBinaryOperatorType.ValueInequality operator defined. (a==b)==false will do the trick, but how about not having an XOR? I find CodeDom's lack of completeness... disturbing.

posted on 28 Ağustos 2006 Pazartesi 21:46:29 UTC  #   
# 19 Ağustos 2006 Cumartesi

ActiveWriter is a DLinq designer like addin for Visual Studio 2005 to design a domain model and to generate code decorated with ActiveRecord attributes.



It supports / will support:

  • Modeling
    Classes (Almost done)
    Class properties (Almost done)
    Setting a property as primary keys (Done)
    Setting more than one property as composite key (TBI)
    Many to One (Done), One to One, Many to Many relations (TBI)
    Nested classes (TBI)
    ... and more (I'm targeting to support the whole ActiveRecord model)
  • Model validation
    Current build validates most common things like classes without names, spaces in class names etc.
  • Drag and drop of table(s) from Server Explorer
    Can place tables, populate properties. I'm working on relations right now.
  • Automatic generation of source code of the model on save.
    Not implemented yet, but I know how to do it. Right now, it goes through .tt file.
  • Multiple database types as drag/drop source.
    Working on SQL Server right now. Oracle and others will follow.

I use the current CTP of DSL Tools to build the base. There are no downloadable bits right now, since I have to get a VSIP licence to make it run without the SDK.

I don't know to what extent I can open the source. I'll sure make the source downloadable but since part of the code is generated by DSL Tools and there's this VSIP licence, I may not be able to licence it under BSD or something. I'll look for it.

Anyway, I believe it will be a nice addin to have for people working with ActiveRecord/NHibernate. I'm doing my best to release a preview in one or two months.

Comments and suggestions are welcome.

posted on 19 Ağustos 2006 Cumartesi 11:02:33 UTC  #   

It's a black hole since its so massive that even a tiny piece of information on it's usage cannot escape out. Start writing an addin for Visual Studio and you'll find lots of information on the net. Enter into realms of Server Explorer, and you'll feel the massive darkness.

I'm coding and addin for Visual Studio 2005 using DSL Tools. Apart from the relatively steep learning curve of DSL Tools, it was going fine. By the very nature of the project, I started thinking on adding drag and drop of tables from Server Explorer. There are some DSRef and UIHierarchy usage examples on the net, so I thought it will be a piece of cake, until I find out there's no simple way of getting the underlying object model for data connections in Server Explorer, thanks to Microsoft's ability to mark everything Server Explorer as Private or Internal.

Long story short, after long nights and hours of Reflector and thousands of evasive maneuvers against the missile fired by my wife, here's how you get the DbConnection instance of Server Explorer holding the tables dropped on your design surface:

        private static DataConnection GetDataConnection(DTE dte, string itemName)


            IntPtr ptr = IntPtr.Zero;



                if (((IServiceProvider)dte).QueryService(ref ServerExplorer, ref IUnknown, out ptr) >= 0)


                    object o = Marshal.GetObjectForIUnknown(ptr);

                    if (o != null)


                        object dataConnectionsNode = GetField(o, "lastBrowseObjectNodeSite");

                        if (dataConnectionsNode != null)


                            INodeSite nodeSite =



                            INodeSite[] nodes = nodeSite.FindChildrenByLabel(itemName);

                            if (nodes != null && nodes.Length > 0)


                                object expNode = GetField(nodes[0], "expNode");

                                if (expNode != null)


                                    object nestedHierarchy = GetField(expNode, "nestedHierarchy");

                                    if (nestedHierarchy != null)


                                        DataConnection connection =

                                            GetProperty(nestedHierarchy, "DataConnection") as DataConnection;

                                        if (connection != null)


                                            return connection;














            return null;


        private static object GetField(object o, string fieldName)


            if (o != null && !String.IsNullOrEmpty(fieldName))

                return o.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(o);


            return null;



        private static object GetProperty(object o, string fieldName)


            if (o != null && !String.IsNullOrEmpty(fieldName))

                return o.GetType().GetProperty(fieldName).GetValue(o, null);


            return null;


Once you get DataConnection, try ConnectionSupport.ProviderObject property to get the actual DbConnection. Happily, VS loaded addins cannot load new assemblies into AppDomain but at least allowed reflection.

posted on 19 Ağustos 2006 Cumartesi 09:49:55 UTC  #   

...but Foreign Key support is just useless, especially for SqlConnection. Just look at the table signature:

ColumnName DataType Description



Catalog the constraint belongs to.



Schema that contains the constraint.






Table Name constraint is part of.



Schema that that contains the table.



Table Name



Type of constraint. Only "FOREIGN KEY" is allowed.



Specifies whether the constraint is deferrable. Returns NO.



Specifies whether the constraint is initially deferrable. Returns NO.

Quite disappointing, since there's no sign of columns involved. And there's no other GetSchema() way to get them. OracleConnection, on the other hand has a collection called ForeignKeyColumns, which returns columns included for a given FK relationship in a given table. Once you have the FK relation, you should query both sides to get the full column list, though, but better than nothing.

So, with SqlConnection, I use sp_fkeys in ActiveWriter. I wish I could just use GetSchema(), to keep things simple. Sad.

posted on 19 Ağustos 2006 Cumartesi 08:59:42 UTC  #