Programmatically check if SQL Replication Components are Installed

By Bill at October 02, 2009 23:16
Filed Under: .Net Programming

I spent some time this week tightening up the code in a project that will actually be released into the wild.  I wanted to make sure that I catch as many errors as possible and put up user friendly messages.

The program uses SMO and RMO to synchronize a local SQL Express database with a master database over the internet.  The program would get some pretty cryptic error messages if SQL Express wasn’t installed, if the expected instance weren’t available or if the replication components weren’t installed.

I was easily able to check if SQL Express was installed and to get a list of the installed instances, but I couldn’t find a way to check if the replication components were installed.  This was annoying because the replication components aren’t installed by default when SQL Express is installed and I was assuming that this situation would come up often.

After some refactoring, I was able to get it to throw an exception with a pretty straight forward error message: “Replication components are not installed on this server. Run SQL Server Setup again and select the option to install replication.”  In fact, I could catch the exception and put up whatever error message I wanted.  Unfortunately, this exception would not occur until the program spent quite a while preparing to do the synchronization.  I really wanted to check for the replication components before I attempted any synchronization.

I spent quite a while googling trying to find something that would work, but couldn’t find anything.  Then I tried checking for the existence of several stored procedures, tables and entries in the SysObjects tables, but nothing I found on a server with the replication components was missing on one without them.

Then I came across the sp_MS_replication_installed system stored procedure.  It’s on all installations and tells exactly what I needed.  I was surprised that with all the searching I did, there was no mention of this handy stored procedure, so I figured I would do my part and document what I found.

The stored procedure is simple enough in that it returns a 0 if the replication components are installed and a 1 if they aren’t.  However, under usual circumstances, it goes a step further and raises an exception if the components aren’t installed.  This is because the procedure reads an entry in the registry to see if the replication components are installed and if they aren’t, it is likely that the entry was never written in the first place.  When it can’t find the registry entry, an exception is thrown.  The only time the stored procedure would return a 1 without throwing an exception is if the replication components were installed at some point and then later uninstalled.

   1: USE [master]
   2: GO
   3: /******Object:  StoredProcedure [sys].[sp_MS_replication_installed]******/
   4: SET ANSI_NULLS ON
   5: GO
   6: SET QUOTED_IDENTIFIER ON
   7: GO
   8:  
   9: --
  10: -- Name: sp_MS_replication_installed
  11: --
  12: -- Descriptions: 
  13: --
  14: -- Parameters: as defined in create statement
  15: --
  16: -- Returns: 0 - success
  17: --          1 - Otherwise
  18: --
  19: -- Security: 
  20: -- Requires Certificate signature for catalog access
  21: --
  22: ALTER procedure [sys].[sp_MS_replication_installed]
  23: as
  24:     set nocount on
  25:     declare @isinstalled int
  26:     select @isinstalled = 0
  27:     declare @retcode int
  28:     
  29:     EXECUTE @retcode = master.dbo.xp_instance_regread 'HKEY_LOCAL_MACHINE', 
  30:         'SOFTWARE\Microsoft\MSSQLServer\Replication',
  31:         'IsInstalled',
  32:         @param = @isinstalled OUTPUT
  33:  
  34:     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) 
  35:     begin
  36:         raiserror (21028, 16, -1)
  37:         return (0)
  38:     end
  39:     
  40:     if (@isinstalled is null or @isinstalled = 0)
  41:     begin
  42:         raiserror (21028, 16, -1)
  43:         return (0)
  44:     end
  45:  
  46:     return (1)

I could use the sp_MS_replication_installed stored procedure as is and catch the exception when it got thrown, but I really don’t like code that relies on exceptions to operate correctly.  Exceptions should be just that – the exception.

   1: private static bool replicationInstalled(string connString) {
   2:     bool result = false;
   3:     using (SqlConnection conn = new SqlConnection(connString)) {
   4:  
   5:         conn.Open();
   6:         using (SqlCommand cmd = new SqlCommand()) {
   7:             cmd.Connection = conn;
   8:             cmd.CommandType = CommandType.StoredProcedure;
   9:             cmd.CommandText = "sp_MS_replication_installed";
  10:             cmd.Parameters.Add("Result", SqlDbType.Int).Direction 
  11:                 = ParameterDirection.ReturnValue;
  12:             cmd.ExecuteNonQuery();
  13:             result = ((int)cmd.Parameters["Result"].Value) == 0;
  14:         }
  15:         conn.Close();
  16:     }
  17:     return result;
  18: }

I took a look at the sp_MS_replication_installed stored procedure and found that all it is doing is calling xp_instance_regread and doing error handling. Since I didn’t like the error handling that sp_MS_replication_installed was doing, I figured I would call xp_instance_regread myself and do my own error handling.

private static bool replicationInstalled(SqlConnection conn) {
bool result = false;
using (SqlCommand cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "xp_instance_regread";
cmd.Parameters.AddWithValue("param1", "HKEY_LOCAL_MACHINE");
cmd.Parameters.AddWithValue("param2", "SOFTWARE\\Microsoft\\MSSQLServer\\Replication");
cmd.Parameters.AddWithValue("param3", "IsInstalled");
cmd.Parameters.AddWithValue("@IsInstalled", 0);
cmd.Parameters["@IsInstalled"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
object returnValue = cmd.Parameters["@IsInstalled"].Value;
if (returnValue != null && returnValue is int) {
result = ((int)returnValue) == 1;
}
}
return result;
}

I changed the replicationInstalled function to call xp_instance_regread directly.  If the registry key exists, the @IsInstalled parameter returns the value from the registry.  That value tells whether the replication components are installed.  If there is no value in the registry, the @IsInstalled parameter returns a null.  I take the value of @IsInstalled and check to see if it is null.  If it is null, I return false.  If it is not null and it is indeed an integer, I return that integer.

Using the new replicationInstalled function my program is able to quickly check if the replication components are installed before attempting to do any synchronization and without throwing any exceptions.  Mission accomplished!

kick it on DotNetKicks.com

Presenting Detail Values as Part of the Master – part 3

By Bill at September 04, 2009 15:39
Filed Under: .Net Programming

This is part three of a three part series on working with master-detail data.  In part one I showed how to present detail values on the master using a utility I wrote called the SubPropertyAccessor. In part two I showed how the SubPropertyAccessor works. In this part, I introduce a descendant of DataGridViewColumn that will allow us to show the indexed detail data in line with the master data as additional columns.  I also introduce a descendent of TypeDescriptionProvider that allows the DataGridView to see the SubProperty as a proper property so that the rest of the grid functionality will still work.

Note: The SubPropertyAccessor was called SubAttributeAccessor in parts one and two.

SubPropertyColumn

The whole point of having detail values appear as part of a master record is to show the data in a grid where the detail values would appear in columns next to the other properties in the record.  In order to do this I created a descendant of DataGridViewColumn called SubPropertyColumn.  Actually, SubPropertyColumn is a descendant of DataGridViewTextBoxColumn.  The DataGridViewTextBoxColumn has most of the functionality I want.  I only need to have the data marshaled in and out of the data bound item in a specific way.

The first thing we need is to know where the SubPropertyAccessor is on the data bound item.  This will be a property on the column that can be set at design time in the DataGridView designer.

  72:         /// <summary>
  73:         /// The name of the property that is the indexed property.
  74:         /// Note that for sorting to work this
  75:         /// should be set to 'Properties'
  76:         /// </summary>
  77:         [Category("Data"),
  78:         DefaultValue("Properties"),
  79:         Description("The name of the property that is the indexed property.")]
  80:         public string IndexedPropertyName {
  81:             get { return fIndexedPropertyName; }
  82:             set {
  83:                 fIndexedPropertyName = value;
  84:             }
  85:         }

Now that we know where to find the SubPropertyAccessor, we need to know which property we are looking for.  This is the index that we will pass into the SubPropertyAccessor.  We need another string property.

 114:         /// <summary>
 115:         /// The index to pass to the indexed property to get the value for this column.
 116:         /// </summary>
 117:         [Category("Data"),
 118:         DefaultValue(""),
 119:         Description("The index to pass to the indexed property to get the value for this column.")]
 120:         public string PropertyIndex {
 121:             get {
 122:                 return base.DataPropertyName;
 123:             }
 124:             set {
 125:                 base.DataPropertyName = value;
 126:             }
 127:         }

This property doesn’t have any backing data of its own.  It is using the DataPropertyName of the base DataGridViewTextBoxColumn.  We do this because the base DataGridColumn bases a lot of functionality on the DataPropertyName property.  For example, if this property is blank the base DataGridColumn doesn’t consider the column to be a data bound column.  If we are going to make use of the functionality provided by the base classes, we going to have to make them happy.  This may seem like a kludge, but it’s better than having to reinvent the DataGridColumn.

More...

kick it on DotNetKicks.com

How To - A Run.GPS Widget for BlogEngine.Net

By Bill at June 09, 2009 02:39
Filed Under: .Net Programming

RunGps WidgetOne of the great things about BlogEngine.Net is how easy it is to create widgets or plug-ins for it.

I’ve created a widget that displays the stats for a user at Run.GPS.

There are two files that go into a widget: the edit.ascx and the widget.ascx.  Both files go in a folder named for the widget.  That folder goes in the widgets folder off of the web project root.

The edit.ascx holds the code that is used to edit the settings for the widget.  The widget.ascx holds the code for the widget itself.

Run.GPS allows users to build a badge that can be embedded in a web page or blog.  The badge is configured with a series of dropdowns which change a box with HTML code at the bottom of the page.  The code is surrounded in an iframe tag. The HTML can be copied and pasted into any web page to embed the badge.

Badge Interface

For the widget to work, it should have the same settings and generate the same HTML code in an iframe tag.  A quick survey of the various settings shows that the dropdowns directly change most of the values in the HTML code.  For example, changing the “Units” dropdown to “Metric” changes to code to include “&units=Metric and changing the “Map Type” dropdown to “NORMAL” changes the code to include&mapType=NORMAL”.

The only tricky part about converting the settings to HTML code is with the width and height attributes in the HTML code.  For each badge type, there are a different set of dimensions.  Rather than spend too much time on this, I just hard coded the dimensions.

More...
kick it on DotNetKicks.com

Presenting Detail Values as part of the Master – part 2

By Bill at May 10, 2009 19:59
Filed Under: .Net Programming

This is part two of a three part series on working with master-detail data.  In part one I showed how to present detail values on the master using a utility I wrote called the SubAttributeAccessor.  In this article I will go into detail as to how the SubAttributeAccessor works. In part three, I’ll introduce a descendant of DataGridViewColumn that will allow us to show the indexed detail data in line with the master data as additional columns.

The SubAttributeAccessor is a class that when added to a parent class is able to present a list of children as an indexed property of the parent.  For example, let’s imagine that we had a class called song and that is has among other properties one that is a list of attribute objects.

public class Song {
public List<Attribute> Attributes {get; set;}
}

The attribute class on the other hand has at least two properties, a key and a value.  The key property is a string that will be used to identify the attribute and the value property would hold the actual value of the attribute.  Rather than a certain type or even an object, the value will hold a byte buffer where we can store anything using serialization.
 
public class Attribute {
public string Key {get; set;}
public byte[] Value {get; set;}
}

These two classes form the basis of the imaginary scenario that I used in part one of this article.  A song can have an unlimited number of attributes.  As things stand, we can add an attribute to a song like so:

Song mySong = new Song();
Attribute myAttribute = new Attribute();
myAttribute.Key = "Tempo";
myAttribute.Value = "slow";
mySong.Attributes.Add(myAttribute);

More...

kick it on DotNetKicks.com

Presenting Detail Values as part of the Master – part 1

By Bill at March 10, 2009 02:52
Filed Under: .Net Programming

This is part one of a three part series on working with master-detail data.  In part one I will show how to present detail values as indexed values on the master using a utility I wrote called the SubAttributeAccessor.  In part two I will show how the SubAttributeAccessor works.  In part three I will introduce a descendant class of DataGridViewColumn called the SubPropertyColumn that will allow showing the detail values as part of the master data.

On more than one occasion I’ve been asked to present master-detail data with the detail data being presented as if they were actually additional fields on the master record.

One time there were literally hundreds of detail records, but only one or two of them would be shown at a time. The master data were names and each of them had a never-ending list of scores.  The names were presented in a table and the last few scores were shown as additional columns with the date of the score as the header.

DataClasses Another time, it was a list of songs where each song had the usual attributes like artist, title, album, etc.  However, each song could also have an unlimited list of “user attributes”.  For example, one user might want to add a tempo and a category to his songs.  Another user might want to add a genre, a year and a rating to his songs.

I’m going to use a simpler version of this last example in this article.  The data will be stored in two tables: a songs table and an attributes table.  The songs table will have three fields: a unique code, an artist and a title.  The attributes table will have four fields: a unique code, a song code, a field name and a value.  The song code will directly relate each attribute to exactly one song.  The field name will be used to identify the the data (e.g.: tempo or score).  The value will store binary data of no particular type.  This is where each of the attributes actually will be stored. There is no limit to the number of additional attributes a song can have.

This master-detail setup is also reflected in the objects used to represent this data in code.  There will be a class named Song and a class named Attribute.  The Song class will own an unlimited list of Attribute.  In the attached solution, I used LINQ to SQL to generate the initial classes.

   1: using System.Collections.Generic;
   2: using System.IO;
   3: using System.Runtime.Serialization.Formatters.Binary;
   4: using System.Text;
   5: namespace SubPropertyColumns {
   6:     partial class Song {
   7:  
   8:         private SubAttributeAccessor<Attribute> fProperties = null;
   9:  
  10:         /// <summary>
  11:         /// Used to access the SongPropertiesAccessor class which
  12:         /// has an indexed property to access the additional
  13:         /// properties.
  14:         /// 
  15:         /// since the Song class already has a member called Attributes,
  16:         /// we'll call this Properties
  17:         /// </summary>
  18:         public SubAttributeAccessor<Attribute> Properties {
  19:             get {
  20:  
  21:                 //the the accessor hasn't been created yet,
  22:                 //create it passing a refrerence to this Song
  23:                 if (fProperties == null) {
  24:                     fProperties = new SubAttributeAccessor<Attribute>(this, "Attributes", "FieldName", "Value");
  25:                 }
  26:  
  27:                 return fProperties;
  28:             }
  29:         }
  30:  
  31:         /// <summary>
  32:         /// This is the default indexed property
  33:         /// It is just a wrapper around the Properties property
  34:         /// that allows us to access the functionality without having
  35:         /// to use the Properties name.
  36:         /// </summary>
  37:         /// <param name="index"></param>
  38:         /// <returns></returns>
  39:         public object this[string index] {
  40:             get {
  41:                 return Properties[index];
  42:             }
  43:             set {
  44:                 Properties[index] = value;
  45:             }
  46:         }
  47:  
  48:     }
  49: }

LINQ to SQL generates the classes as partial classes which allows us to add a few properties of our own.

The first thing we add, on line 8, is a private field of type SubAttributeAccessor<T>.  The SubAttributeAccessor does all of the work accessing the list of attributes and presenting them as an indexed property.

Next, on line 18,  we add a public property to access the SubAttributeAccessor.  The property checks to see if SubAttributeAccessor is created and if it isn’t it creates it.  When creating the SubAttributeAccessor, on line 24, we need to add a few important parameters.  First, we need to include the type parameter <Attribute>.  This defines what the type of each of the attributes will be.  In our case, the type of the attribute is Attribute. We also need to add a reference to the object itself and the names of several fields.  We need the reference to the object itself so that the SubAttributeAccessor can have access to the list of attributes.  Then, we need to tell the SubAttributeAccessor the name of the property on the object that is the list of attributes.  In this case it is “Attributes”.  We also need to tell the SubAttributeAccessor the name of the property on each of the attributes that will be used as the index.  In this case it is “FieldName”.  Finally, we need to tell the SubAttributeAccessor the name of the property on each of the attributes that will be the actual value of the attribute.  In this case it is “Value”.  It is important to note that the first property name is the name of a property on the master object – it is the property that returns a list of detail objects.  In this case it is the Attributes property on the Song class itself.  The next two property names are names of properties on the detail object.  In this case, they are the FieldName and Value properties of the Attribute class.  It is also important to note that we named the SubAttributeAccessor property “Properties” because the Song class already has a property named Attributes.

Now that we have a SubAttributeAccessor hooked up to our Song class, we can already write code like:

   1: Song MySong = new Song();
   2: MySong.Properties["Tempo"] = "Medium";
   3: MySong.Properties["Rating"] = 5;

However, we can take this one step further.  On line 39, we add a default indexed property that is just a wrapper around the Properties property.  This allows us to drop the poorly named .Properties and just use the index directly on Song like so:

   1: Song MySong = new Song();
   2: MySong["Tempo"] = "Medium";
   3: MySong["Rating"] = 5;

At this point we’re able to access the detail data as indexed values of the master.  In the next part I’ll show how the SubAttributeAccessor works.  Finally, in the third part, I’ll introduce a descendant of DataGridViewColumn that will allow us to show the indexed detail data in line with the master data as additional columns.

Source Code : SubPropertyColumns.zip (485 KB)

kick it on DotNetKicks.com

New Facebook Application – My Playlist

By Bill at February 26, 2009 14:11
Filed Under: .Net Programming, Random, Music

I’ve written a new Facebook application called My Playlist. The application displays a playlist like the one shown here on your profile either on your wall or on your boxes tab.  It works by reading an XML file version of your playlist off of any FTP or WWW server on the internet.

The easiest way to get an XML export of your playlist is to use a plug-in for your music player.  Brandon Fullerhas written plug-ins for iTunes, Windows Media Player, WinAmp and Yahoo! Music Engine.

Brandon has also written a Facebook application that will show information about the last song you played.  I took that idea and expanded it into the entire playlist.

I used the Facebook.Net toolkit to write the application using .Net in VisualStudio 2008.  There were some interesting hoops I had to jump through to get the playlist to show in the profile at all and to get the “Add To Profile” button to show up on the application start page.  I think that story deserves an article all of its own.  I hope to get around to writing that sometime soon.

Testers Needed

Right now, I need a few patient people to actually test this application out.  I say patient because there is a little bit involved in getting the plug-in installed and working and because after going through all that, there’s a small possibility that it won’t work at all.

One of the problems is that Brandon Fuller’s plug-in costs $15.  I will get a license for anybody who is willing to test this for me.

Another problem is that the output of the plug-in, the XML file, needs to be hosted somewhere on the internet where it can be downloaded by my program.  This means an FTP or WWW server.  I suspect that most people don’t have their own servers and wouldn’t know how to find one.  Luckily, I do have an FTP server and will gladly host a place for you to put your XML file.

All this leaves is actually installing the plug-in and setting a few settings and I can help out with that.

If I haven’t lost you yet and you are still reading and you are interested in trying this out, let me know. 

If you’re not sure that you want to help out, don’t worry about it.  This is just for fun and isn’t important at all.  I won’t hold it against you if you don’t try my application.  Really.  If you still want to help put, leave a comment on the application page or become a fan.

[Link to application on Facebook]

kick it on DotNetKicks.com

Arithmetic in Generic Classes

By Bill at February 17, 2009 18:33
Filed Under: .Net Programming

I work quite a bit with matrices. I work with them enough that at some point I decided to create my own generic classes for a matrix and a half matrix. Among other things, I wanted my classes to provide a method to calculate the sum of items in a row or column. I immediately had a problem. How does one calculate the sum of two generic objects?

 To simplify things, let's say that we're working with a descendant of List<T> and we want to add a method called Sum().

We start by deriving a class from List<T>:

class SummableList : List{}

Let's go ahead and add the Sum()method:

class SummableList : List {
public T Sum() {
T result = default(T);
foreach (T item in this)
result += item;
return result;
}
}

Unfortunately, that will not compile.  It won't compile because the compiler doesn't know how to add two objects together.  In .Net a type parameter (the T in List<T>) that is not constrained is assumed to be of type System.Object and there's not much you can do with a plain old object.

More...

kick it on DotNetKicks.com

Authors

  RSS Feed Bill Fugina

Bill is Director of Technology for Coleman Insights. He enjoys programming, software design, walking, reading, dining out and watching movies, most of which he enjoys even more when he doing them with his wife, Deb, and or his son, Isaac.  Bill and Isaac are working on a video game, but they haven't made very much progress yet.

  RSS Feed Debra Hill

Deb dabbled in Project Management in the Advertising industry for (too) many years. She has happily ditched that and is taking some time to decide what is next career-wise. She enjoys gardening, knitting, sewing and various other crafty things. She also enjoys vegetating on the weekends with the family.

RSS Feed Isaac Hill-Fugina

Isaac has his own blog called Isaac's Place.

Recent Comments

Comment RSS

Bill's Run.GPS Stats

Training Sessions 16
Total Distance 50.17 mi
Total Time 0.11:50:02
Calories 6961 kcal
Average Speed 4.24 mph
Min Altitude -157 ft
Max Altitude 590 ft
Total Ascent 3289 ft
Total Descent 2351 ft