Re-Installing Windows Sharepoint Services

Programming, Software July 2nd, 2008

Part of my job with Contract5 I have to do development on the Windows Sharepoint Services platform.  In order to facilitate this I setup a VMWare virtual machine with Windows 2008 Server, Sharepoint and Visual Studio 2008.

However, I made the bad error of deciding to change the computer name once all of the above was installed.  Unfortunately I didn’t realise that the computer name was so deeply rooted in the Sharepoint installation.  I also tried reverting the computer name back to it’s original value but this didn’t seem to make much difference, if anything it made the situation worse.

No amount of removing Sharepoint and re-installing it made any difference as the original settings still seemed to be there.  Eventually I gave in and completely rebuilt the VM.

I have since discovered that my problems were all due to the four Sharepoint databases that got installed the first time round which are not removed when Sharepoint is un-installed.  I have found a this knowledge base article on removing the Sharepoint databases: http://support.microsoft.com/kb/920277

Levels of Enthusiasm Cycle

Programming June 5th, 2008

Based on the Level of Enthusiasm blog post from Rick Strahl, I have come up with what I think is my enthusiasm cycle whilst developing software:development_cycle

Typically, for me, everything is based around a default state of “Rat race”. If nothing changes for a log period of time I’ll enter the “In a rut” state the only thing that really breaks that state for me is going on holiday for some “Down time”. This gets me back into the “Rat race” state.

If, whilst in the “Rat race” state I come up to a deadline, I move into the “Pressure cooker” state. I don’t know if this is peculiar to me but it is normally from this state that i enter the “Inspired & wired” state. When the rush is over it’s back to the “Rat race”.

This is a very generalised cycle and things may not always work like that. I may be in a rut and then come up against a deadline, or whilst having some down time I’ll have a flash of inspiration and come back to work raring to get coding.

Is Microsoft About To Buy Zend?

PHP, Programming, Technology May 20th, 2008

Microsoft has been trying to make itself F/OSS friendly recently.  From agreeing not to sue open source projects to working to provide a bridge between it’s proprietary source management system (TFS) and the much loved open source alternative SubVersion.  Microsoft seems to be trying its best but still appears to be keeping open source at arms length.

The question is: is Microsoft ready to get into bed with open source itself.  Enter Zend.  Zend is an Israeli company that has grown up around the open source scripting engine PHP.   Previously Microsoft announced that it would be working with Zend to provide better support for PHP under Windows Server.

In the last day or so it has become apparent that Zend is laying some of it’s staff. Erick Schonfeld has speculated that this may be to make Zend more attractive to a prospective purchaser.  With Microsoft on the verge of finally to a deal to buy (some if not all) Yahoo, it may Zend may also look attractive if Microsoft is to continue supporting the applications that Yahoo has running on PHP.

There is also the long awaited dynamic language support for .Net.  Maybe PHP could be leveraged to bring more hobbyist developers over to the .Net platform.  Obviously there is the question of getting the .Net framework ported over to alternative operating systems, however Silverlight has demonstrated that they might not be adverse to that idea.

Of course, Oracle has also previously shown an interest in PHP and it would sit nicely alongside MySQL, which that previously purchased.  And then there is IBM, who also seem to be embracing open source as their extensive use, distribution and support of Java show.

Character Counter

.NET, Software February 8th, 2008

Whilst reading an article I was curious about the number of commas and full-stops that the author used - when you become an editor of a newsletter you start to think about things like this.  After hunting around the various utilities on my system I discovered that I didn’t have anything that could easily do this.  So, I did what any self-respecting programmer would do and threw together a quick app to do it for me.

I have made both the source code and pre-compiled binary available for download under a BSD license (share, remix, no endorsement).  It is written in C# and requires the .Net 2.0 framework, if you want to compile the source you will probably require MS Visual Studio (Express should be ok), although it may work with SharpDevelop or Mono.

It is a console application (sorry, no pretty GUI this time) that reads the contents of input.txt (in the same directory as the app), it then counts the occurrences of each character and outputs the results to the console. Simple!

If you make any improvements to the code please leave a comment and/or email the changes to me: gringod [at] gmail [dot] com.

Test Driven Porting

.NET, Bell Ringing, Programming November 20th, 2007

Recently I’ve had reason to take an code library written in C++ and port it to C#.  Whilst I dabbled in C++ on a compilers course at university, I hated it then and I still hate it now.  I personally think it’s an abomination and should be consigned to the great garbage collector in the sky.   Whilst I can just about read the C++ syntax there is a lot that I don’t understand about it.

The library I was porting had semi reasonable documentation outlining what classes exist and their methods and a brief description of the overall usage.  This gave me a good starting point, however the documentation didn’t include example usages and expected results, for this I was forced to delve into the code.

One development paradigm I have been interested in but have been unable to find a decent project to test it on is Test-Driven-Development and this seemed like the perfect project to try it on.  So I set to work on the first iteration getting the test set up.   Without knowing exactly what results I should be expecting I was finding it hard going, so once again I dived back into the old code.

Thankfully, the developers of the C++ library had create a fairly comprehensive set of unit tests and with my limited C++ knowledge and a text editor with RegEx Find & Replace I was quickly able to convert their unit tests into NUnit based unit tests.

For example, what started out life as:

 1: void test_row_multiply_change(void)
 2: {
 3:  row r;
 4:  RINGING_TEST( ( r *= change( 6, "X" ) ) == "214365" );
 5:  RINGING_TEST( ( r *= change( 6, "1" ) ) == "241635" );
 6:  RINGING_TEST( ( r *= change( 8, "X" ) ) == "42615387" );
 7:  RINGING_TEST( ( r *= change( 5, "3" ) ) == "24651387" );
 8:  
 9:  RINGING_TEST( row( "214365" ) * change( 7, "5" ) == row( "1234675" ) );
 10: }

Quickly became:

 1: [Test]
 2: public void TestMultiplicationByChange()
 3: {
 4:  Row r = new Row();
 5:  Assert.AreEqual((Row)"214365", r *= new Change(6, "X") );
 6:  Assert.AreEqual((Row)"241635", r *= new Change(6, "1"));
 7:  Assert.AreEqual((Row)"42615387", r *= new Change(8, "X" ));
 8:  Assert.AreEqual((Row)"24651387", r *= new Change(5, "3"));
 9:  
 10:  Assert.AreEqual((Row)"1234675", new Row("214365") * new Change(7, "5"));
 11: }

Now, with a full set of unit tests at my disposal I was quickly able to bash away at the library and very quickly got working code without the need to trawl through ghastly C++ code.

Hooray for Test-Driven-Development and three cheers for Test-Driven-Porting.

ps. The library I’m porting is an open source library for Bell Ringing - yes I know I’m a geek but anyone that has followed everything else in this post must also be a geek ;-).  Once I’m finished I will be releasing my code under an open source license as well, I just need to pick the right one.

pps. I may have exaggerated my hate of C++ a little.  I believe all languages have their place, even the esoteric languages like LOLCode.

kick it on DotNetKicks.com

More Fun With QR-Codes

Bookmarks, Programming, Technology October 24th, 2007

bomb I promise this will be the last post for a while to include a QR-Code.  If you don’t know what a QR-Code is, go read about it on wikipedia.  There are several QR-Code readers out there but I have personally chosen to go with the Kaywa Reader.  I also use the Kaywa QR-Code generator.

The reason for this post was to play with an idea I came up with after reading the Wikipedia article on QR-Codes.  One of the images they show is of an picture encoded into the code.  Whilst I haven’t yet been able to figure out how they encoded the image into the code I have made another discovery.  It turns out that QR-Codes contain a lot of redundancy.  It is possible to loose up to 30% of the code and still be able to read its content.

I’ve found that it is possible to paste an image over the top of the QR-Code.  My experiments so far indicate seem to indicate the image needs to cover less than 30%.  I haven’t had to time to find out how the QR-Codes are structured.  It may be possible in re-structure the data so that more of it can be lost to the embedded image.

Technorati Tags: , , ,

System.IO.Path.Combine()

.NET, Programming October 12th, 2007

Many, many times in my programming life I have seen people causing themselves all sorts of problems as the try and concatenate paths for file and directories.  They’re always trying to work if the path already ends with a directory separator or not.  And then there are the cross platform systems that try  to workout what the directory separator should be.

With the release of the .Net platform,  Microsoft gave developers that need to handle file system operations a wonderful, but underused, utility class: System.IO.Path.  One of the methods on this class is Combine().  It take two arguments: path1 (string) and path2 (string), and intelligently combines them.

That’s it!  No more messing around with string concatenation or endless if statements or figuring out if it should be a forward or backslash… just Path.Combine().

kick it on DotNetKicks.com

Really Simple Dependency Injection

.NET, Programming September 30th, 2007

Having just started a new job I find it interesting to see the way that the other developers I’m working with do things. One of the things I found in the code was for doing dependency injection. I’m not going to analyse that code as but what I will say is that I managed to replace 10 lines of code with just 3.

Without further ado here is the C# code:

public static T Get<T>() where T : class
{
string implName = Program.Settings[typeof(T).Name].ToString();
object concrete = Activator.CreateInstance(Type.GetType(implName));
return (T)concrete;
}

So what can you do with this code? Well, the way it is written means that you can create an object, the class of which is defined in a configuration file. This allows you to program to an interface but decide the concrete class in the configuration file. The method above will find the class defined for the interface being passed in, create an object of that type and return the object cast to the type of the interface.

The code used to call the method:
IPlugin plugin = PluginFactory.Get<IPlugin>();

plugin.OutputMessage("hello, world!");

The definition in the config file:
<setting name="IPlugin" serializeAs="String">
<value>GrinGod.Dependency.PluginTwo.PluginTwo,GrinGod.Dependency.PluginTwo</value
</setting>

I’m sure I haven’t explained terribly well, so I’ve thrown together a simple example that you can download. I should point out that this code a very simple example of dependency injection, it doesn’t handle passing values to the constructor of the object being instantiated, although it would be simple to add that. Also, the example I have included statically links to the two plugin assemblies, this could be changed such that the plugin assemblies are dynamically loaded using Assembly.Load()

If you want a more fully featured implementation of dependency injection you should check out the Spring.Net framework.
kick it on DotNetKicks.com

Technorati Tags: , , ,

RFID Experiment Kit

Programming, Technology March 1st, 2007

Being the geeky-programmer type that I am (no, I’m not a goth or an emo!) I’m always interested when the secrets of the few becomes the technology of the masses. Today I almost wet my pants when I opened the Make: blog feed in Google Reader and saw a USB RFID reader.

Depending on who you ask, RFID technology is either the “Mark of the Beast”, or a global panacea destined to rescue the grocery stores and Walmarts of the world from shoplifting. But any good geek knows that RFID is nothing more than tiny microchips powered by RF induction that store and broadcast a small bit of data. Want to learn more? Rather than rip apart your passport you can pick up this nifty RFID Experimentation Kit with over a dozen types of RFID tags, a USB based RFID reader and instructions for tons of insidious RFID projects. You even get a cool bio-implantable type of RFID Tag which you should never ever load into a blowgun and implant in any of your coworkers because it’s not surgically sterilized.

It only £50 and I want one! If anyone has heard my ideas about a proximity reminders will know what my first project would be. If anyone is stuck about what to get me for my birthday, or even just as a random gift, then get me one of these. I will be your friend forever!

Now, if only they did a bluetooth version :D

Scripting Permissions in SQL Server

Programming February 27th, 2007

I shalln’t tell you my exact reasons for discovering this information but believe me when I say it took about an hour of clicking several thousand checkboxes and thinking “there must be a better way of doing this”.

What I was doing was setting permissions on an MS SQL Server database that didn’t have roles set up in it. What I needed was a way to export roles and their permissions from one database and insert them into another database. The “Script Role” feature in SQL Server Management Studio on created a role, it didn’t script the effective permissions of the role.

Luckily I found the How to Script User and Role Object Permissions in SQL Server page on Sql-Server-Performance.com. That provides sql scripts that interrogates an SQL Server database and role/user and generates a script that can be used to set up that role/user in another database.

Obviously it goes without saying that you should be using roles in databases and assigning users to roles at the server level, not the database level, as when start moving databases around the roles will be moved but the users may not exists on the next server. Also, wherever possibly you should be using Windows Authentication and not SQL Server Authentication and you should not be using the SA account account.

Just in case the above site goes down I’ll include the script for export role permissions below:

--Written By Bradley Morris
--In Query Analyzer be sure to go to
--Query -> Current Connection Options -> Advanced (Tab)
--and set Maximum characters per column
--to a high number, such as 10000, so
--that all the code will be displayed.

DECLARE  @DatabaseRoleName [SYSNAME]
--SET @DatabaseRoleName = '{Database Role Name}'

SET @DatabaseRoleName = 'role_name_goes_here'

SET NoCount  ON

DECLARE  @errStatement      [VARCHAR](8000),
         @msgStatement      [VARCHAR](8000),
         @DatabaseRoleID    [SMALLINT],
         @IsApplicationRole [BIT],
         @ObjectID          [INT],
         @ObjectName        [SYSNAME]

SELECT @DatabaseRoleID = [uId],
       @IsApplicationRole = CAST([IsapProle] AS BIT)
FROM   [dbo].[sysUsers]
WHERE  [Name] = @DatabaseRoleName
       AND ([IssqlRole] = 1
             OR [IsapProle] = 1)
       AND [Name] NOT IN ('public',
                          'INFORMATION_SCHEMA',
                          'db_owner',
                          'db_accessadmin',
                          'db_securityadmin',
                          'db_ddladmin',
                          'db_backupoperator',
                          'db_datareader',
                          'db_datawriter',
                          'db_denydatareader',
                          'db_denydatawriter')

IF @DatabaseRoleID IS NULL
  BEGIN
    IF @DatabaseRoleName IN ('public',
                             'INFORMATION_SCHEMA',
                             'db_owner',
                             'db_accessadmin',
                             'db_securityadmin',
                             'db_ddladmin',
                             'db_backupoperator',
                             'db_datareader',
                             'db_datawriter',
                             'db_denydatareader',
                             'db_denydatawriter')
      SET @errStatement = 'Role ' + @DatabaseRoleName + ' is a fixed database role and cannot be scripted.'
    ELSE
      SET @errStatement = 'Role ' + @DatabaseRoleName + ' does not exist in ' + Db_name() + '.' + CHAR(13) + 'Please provide the name of a current role in ' + Db_name() + ' you wish to script.'
    RAISERROR (@errStatement,16,1)
  END
ELSE
  BEGIN
    SET @msgStatement = '--Security creation script for role ' + @DatabaseRoleName + CHAR(13) + '--Created At: ' + CONVERT(VARCHAR,Getdate(),112) + REPLACE(CONVERT(VARCHAR,Getdate(),108),':','') + CHAR(13) + '--Created By: ' + Suser_name() + CHAR(13) + '--Add Role To Database' + CHAR(13)
    IF @IsApplicationRole = 1
      SET @msgStatement = @msgStatement + 'EXEC sp_addapprole' + CHAR(13) + CHAR(9) + '@rolename = ''' + @DatabaseRoleName + '''' + CHAR(13) + CHAR(9) + '@password = ''{Please provide the password here}''' + CHAR(13)
    ELSE
      BEGIN
        SET @msgStatement = @msgStatement + 'EXEC sp_addrole' + CHAR(13) + CHAR(9) + '@rolename ''' + @DatabaseRoleName + '''' + CHAR(13)
        PRINT 'GO'
      END
    SET @msgStatement = @msgStatement + '--Set Object Specific Permissions For Role'
    PRINT @msgStatement
    DECLARE _sySobjects CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR
    SELECT DISTINCT ([sySobjects].[Id]),
                    '[' + User_name([sySobjects].[uId]) + '].[' + [sySobjects].[Name] + ']'
    FROM   [dbo].[sysProtects]
           INNER JOIN [dbo].[sySobjects]
             ON [sysProtects].[Id] = [sySobjects].[Id]
    WHERE  [sysProtects].[uId] = @DatabaseRoleID
    OPEN _sySobjects
    FETCH NEXT FROM _sySobjects
    INTO @ObjectID,
         @ObjectName
    WHILE @@FETCH_STATUS = 0
      BEGIN
        SET @msgStatement = ''
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 193
                          AND [ProtectType] = 205)
          SET @msgStatement = @msgStatement + 'SELECT,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 195
                          AND [ProtectType] = 205)
          SET @msgStatement = @msgStatement + 'INSERT,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 197
                          AND [ProtectType] = 205)
          SET @msgStatement = @msgStatement + 'UPDATE,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 196
                          AND [ProtectType] = 205)
          SET @msgStatement = @msgStatement + 'DELETE,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 224
                          AND [ProtectType] = 205)
          SET @msgStatement = @msgStatement + 'EXECUTE,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 26
                          AND [ProtectType] = 205)
          SET @msgStatement = @msgStatement + 'REFERENCES,'
        IF len(@msgStatement) > 0
          BEGIN
            IF RIGHT(@msgStatement,1) = ','
              SET @msgStatement = LEFT(@msgStatement,Len(@msgStatement) - 1)
            SET @msgStatement = 'GRANT' + CHAR(13) + CHAR(9) + @msgStatement + CHAR(13) + CHAR(9) + 'ON ' + @ObjectName + CHAR(13) + CHAR(9) + 'TO ' + @DatabaseRoleName
            PRINT @msgStatement
          END
        SET @msgStatement = ''
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 193
                          AND [ProtectType] = 206)
          SET @msgStatement = @msgStatement + 'SELECT,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 195
                          AND [ProtectType] = 206)
          SET @msgStatement = @msgStatement + 'INSERT,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 197
                          AND [ProtectType] = 206)
          SET @msgStatement = @msgStatement + 'UPDATE,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 196
                          AND [ProtectType] = 206)
          SET @msgStatement = @msgStatement + 'DELETE,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 224
                          AND [ProtectType] = 206)
          SET @msgStatement = @msgStatement + 'EXECUTE,'
        IF EXISTS (SELECT *
                   FROM   [dbo].[sysProtects]
                   WHERE  [Id] = @ObjectID
                          AND [uId] = @DatabaseRoleID
                          AND [Action] = 26
                          AND [ProtectType] = 206)
          SET @msgStatement = @msgStatement + 'REFERENCES,'
        IF len(@msgStatement) > 0
          BEGIN
            IF RIGHT(@msgStatement,1) = ','
              SET @msgStatement = LEFT(@msgStatement,Len(@msgStatement) - 1)
            SET @msgStatement = 'DENY' + CHAR(13) + CHAR(9) + @msgStatement + CHAR(13) + CHAR(9) + 'ON ' + @ObjectName + CHAR(13) + CHAR(9) + 'TO ' + @DatabaseRoleName
            PRINT @msgStatement
          END
        FETCH NEXT FROM _sySobjects
        INTO @ObjectID,
             @ObjectName
      END
    CLOSE _sySobjects
    DEALLOCATE _sySobjects
    PRINT 'GO'
  END