Archive

Archive for February, 2009

Clustering Quest ChangeDirector

February 23, 2009 Leave a comment

Whilst Quest declare that ChangeDirector 2.1 supports Clustering I’m not convinced it goes the whole hog. However your intrepid Random-Thunker has gone through the small number of extra steps required to make it so.

First off if you’ve not already done so, install ChangeDirector onto both nodes using the normal methods and validate that it works just fine by moving the Sql Cluster service through each node. Validate with ChangeDirector that the agent is running correctly.

Now shut the Service down and modify the configuration file ON EACH NODE. For me the configuration file was on C:\Program Files\Quest Software\Quest Change Director for SQL Server\[SqlClusterName]\QuestChangeTrackerAgent.exe.config. Update this to point the Trace and Log folders on one of the shared drives used by the cluster. I used the drive dedicated to normally storing dumps and backups onto which kept it away from affecting the other drives in the SAN whilst still making it always available to the cluster.

Fire up the service again on the active node to verify all is well still then shut it down again and this time change it’s startup type from Automatic to Manual.

Create a new Generic Service Cluster Resource in the Cluster Administrator. The Service name to use is Quest Change Tracker Agent. I added a couple of dependencies for both the drive I was using to store the logs and traces on and also Sql Server itself. In addition I elected to change the settings to not affect the group; this way if it should so something daft it wasn’t going to take the whole cluster with it. For me the continuous availability of the cluster trumps ChangeDirector – your individual mileage may, as they oft say, vary. And oh, there are no registry keys to replicate so you don’t need to worry on that front.

Now you should be able to fire up the resource in the Cluster Administrator and off you go. For a final test move the Sql Cluster through each node verifying that it’s seen by ChangeDirector at all times.

Windows 2003, ChangeDirector 2.1.0.87

Unverifiable Passwords with Sql Configuration Manager

February 23, 2009 Leave a comment

This was an odd one and much akin to a previous recent incident I’d had with the configuration manager (albeit this time on a totally different server); this last weekend we had one of our regular ‘let’s all work through the night’ maintenance windows. Such events are never fun to do but made even worse when the strangest of things happen.

This weekend it was the turn of the Sql Configuration Manager and it’s stubborn refusal to validate a new account password. No matter how many times I tried it would not take the new password, regardless if I pasted it in or typed it in. Each time I’d see an entry in the Security log telling me the attempt to logon with the credentials had failed.

Given that it was now getting close to 3AM I decided another approach based off the prior experience; I fired up the Services applet and pasted the password directly in there.

Well, would you Adam and Eve it – it only bloody worked.

Don’t have a good reason or explanation for this one other than – WTF?

Still, whatever it takes.

Sql Server 2005 SP2 No CR’s.

Categories: Sql Server, Workarounds

Maintaining hierarchical names in TFS 2008 from Project 2007

February 12, 2009 Leave a comment

Waiting for the nested hierarchical tasks functionality in TFS 2010 is not currently an option for me right now in my quest to process tasks from MS Project 2007. Nor is manually updating each task title within Project to keep some sort of structure since that would be a real pain and be largely un-maintainable once you have more than a few tasks.

Now it’s been a long while since I last messed around with VBA, so this is probably pretty ugly – however it does do the trick. In addition to keeping the hierarchical naming structure, it also marks summary tasks as not publishable to avoid polluting TFS with them.

The entry point is HierarchicalTaskNames().

Dim TitleStack As Collection
Dim taskId As Integer

Sub
RecursiveScanAndFix(ByRef t As Task)
Dim child As Task
Dim i As Integer
Dim
text As String

text = t.Name

' If this task has children then add the name to the stack and continue on down
If t.OutlineChildren.Count > 0 Then
Push(text)
t.Text25 = "No"
' Now look for the children

For Each child In t.OutlineChildren
RecursiveScanAndFix(child)
Next child

Pop()

Else
' No, no children found. So these will be actual tasks. Therefore we need to prepend the hierarchy name onto the task
' First off look to see if we've already named this. If so we'll strip the previous hierarchical name off before we start
If Left(text, 1) = "[" Then
' Yes we have. Hunt down the last ] and remove it from the text
For i = Len(text) To 1 Step -1
If Mid(text, i, 1) = "]" Then
text = Mid(text, i + 1)
Exit For
End If
Next
text = Trim(text)
End If

' Now add the hierarchical name to the task title

t.Name = GetTitleFromStack & " " & text

taskId = t.ID
End If
End Sub

Sub
HierarchicalTaskNames()
Dim t As Task
taskId = 1
TitleStack = New Collection

While taskId <= ActiveProject.NumberOfTasks
t = ActiveProject.Tasks(taskId)
If t.OutlineChildren.Count > 0 Then
RecursiveScanAndFix(ActiveProject.Tasks(taskId))
End If
taskId = taskId + 1
End While
End Sub

Function
Pop() As String
If
TitleStack.Count > 0 Then
Pop = TitleStack.Item(TitleStack.Count)
TitleStack.Remove(TitleStack.Count)
End If
End Function

Function
Push(ByVal Title As String)
TitleStack.Add(Title)
End Function

Function
GetTitleFromStack() As String
GetTitleFromStack = "[ "
Dim i As Integer

For
i = 1 To TitleStack.Count
GetTitleFromStack = GetTitleFromStack & TitleStack.Item(i)
If i <> TitleStack.Count Then
GetTitleFromStack = GetTitleFromStack & " | "
End If
Next

GetTitleFromStack = GetTitleFromStack & " ]"
End Function

MS Project 2007 SP1

Categories: Office, Project, TFS, VBA

Wix Rollin’

February 10, 2009 1 comment

What a difference a few hours makes. Yesterday afternoon I was feeling mightily peeved off that Microsoft had still not put any support in MSBuild for building Visual Studio Deployment Projects. I was with the folks in the various forums, blogs and other dark places where we all visit who cried ‘foul!’ and ‘unfair’ and MS’s decision.

That was however until I rediscovered WiX – Windows Installer XML.

I had seen WiX once before (quite some time before) and at the time I dismissed it as ‘Something I might care about later’. My TFS Build at the time were creating libraries or other code that didn’t required an installer so I really paid it no heed. Well, yesterday was the day that I cared about it.

MS obviously have put a lot of faith in WiX – I read somewhere that they even use it internally to build the Office 2007 installer – if this is indeed the case then it’s no small feat. The installers I needed to create where by no-means on the same level so I figured at that time, when in Rome.

Now granted WiX is a bit of a learning curve but there are tools out there that make your life easy – especially when you’ve already got a .vdproj that you need to WiXify. When converting existing deployment projects there’s a slight reverse around face in that it actually makes more sense to start with the end-project and work your way back to a new installer than attempt to build a new WiX project from scratch.

So, in an attempt to help clarify a few steps, here’s my trip down converting an existing deployment project into a new fangled WiX project – complete with the need to reference binaries as part of the MS Enterprise Application block 4.1.

Caveat Emptor: I’m not saying that these steps are the most efficient – however they did work for me!

NB: I was using the WiX Beta 3 build 4805.0 to create my packages and Visual Studio 2008 Team Suite along with TFS 2008 to create my projects and builds.

Step 1: Reverse engineer to deployment project.

Sure you have the source, so why reverse engineer anything? Well, in our case the project builds an MSI file which is pretty easy to decompile given the tools available in WiX. So, first off copy the MSI to a temporary work area and execute the Dark WiX executable to decompile the MSI into it’s constituent parts – and create a WiX project file as a result.

C:\tmp\1 Day\WiX>"C:\Program Files\Windows Installer XML v3\bin\dark.exe" -x Binary LogProcessorServiceSetup.msi LogProcessorServiceSetup.Wxs
Microsoft (R) Windows Installer Xml Decompiler version 3.0.4805.0
Copyright (C) Microsoft Corporation. All rights reserved.

LogProcessorServiceSetup.msi
C:\tmp\1 Day\WiX\LogProcessorServiceSetup.msi : warning DARK1060 : The _VsdLaunchCondition table is being decompiled as a custom table.dark.exe : warning DARK1065 : The AdvtUISequence table is not supported by the WiX toolset because it has been deprecated by the Windows Installer team. Any information in this table will be left out of the decompiled output.
C:\tmp\1 Day\WiX\LogProcessorServiceSetup.msi : warning DARK1062 : The ModuleSignature table can only be represented in WiX for merge modules. The information in this table will be left out of the decompiled output.
C:\tmp\1 Day\WiX\LogProcessorServiceSetup.msi : warning DARK1062 : The ModuleComponents table can only be represented in WiX for merge modules. The information in this table willbe left out of the decompiled output.
C:\tmp\1 Day\WiX\LogProcessorServiceSetup.msi : warning DARK1066 : The MsiPatchHeaders table is added to the install package by a transform from a patch package (.msp) and not authored directly into an install package (.msi). The information in this table will be left out of the decompiled output.C:\tmp\1 Day\WiX\LogProcessorServiceSetup.msi : warning DARK1066 : The Patch table is added to the install package by a transform from a patch package (.msp) and not authored directly into an install package (.msi). The information in this table will be left out of the decompiled output.C:\tmp\1 Day\WiX\LogProcessorServiceSetup.msi : warning DARK1066 : The PatchPackage table is added to the install package by a transform from a patch package (.msp) and not authored directly into an install package (.msi). The information in this table will be left out of the decompiled output.dark.exe : warning DARK1058 : The AdvtExecuteSequence table contains an action 'MsiUnpublishAssemblies' which is not allowed in this table. If this is a standard action then it is not valid for this table, if it is a custom action or dialog then this table does not accept actions of that type. This action will be left out of the decompiled output.
C:\tmp\1 Day\WiX>

Getting a directory listing gives us the output of the decompilation process.


C:\tmp\1 Day\WiX>dir /s
Volume in drive C has no label.
Volume Serial Number is 045E-5666

Directory of C:\tmp\1 Day\WiX

02/10/2009 10:39 AM <DIR> .
02/10/2009 10:39 AM <DIR> ..
02/10/2009 10:39 AM <DIR> Binary
02/10/2009 10:36 AM 434,688 LogProcessorServiceSetup.msi
02/10/2009 10:39 AM 91,008 LogProcessorServiceSetup.Wxs
2 File(s) 525,696 bytes

Directory of C:\tmp\1 Day\WiX\Binary

02/10/2009 10:39 AM <DIR> .
02/10/2009 10:39 AM <DIR> ..
02/10/2009 10:39 AM <DIR> Binary
02/10/2009 10:39 AM <DIR> File
0 File(s) 0 bytes

Directory of C:\tmp\1 Day\WiX\Binary\Binary

02/10/2009 10:39 AM <DIR> .
02/10/2009 10:39 AM <DIR> ..
02/10/2009 10:39 AM 5,088 DefBannerBitmap
02/10/2009 10:39 AM 65,032 InstallUtil
02/10/2009 10:39 AM 227,832 MSVBDPCADLL
02/10/2009 10:39 AM 318 NewFldrBtn
02/10/2009 10:39 AM 318 UpFldrBtn
02/10/2009 10:39 AM 11,225 VSDNETCFG
6 File(s) 309,813 bytes

Directory of C:\tmp\1 Day\WiX\Binary\File

02/10/2009 10:39 AM <DIR> .
02/10/2009 10:39 AM <DIR> ..
02/10/2009 10:36 AM 7,680 _0A137FFDF05A958D558EC9E2DC48F39A
02/06/2009 07:48 AM 1,326 _2CB35E650D766290C1E57911DE7343FA
02/10/2009 10:36 AM 9,216 _35C91406817D7569FFBF7DDCC6ADDC59
02/10/2009 10:35 AM 13,312 _4EE2E5745FE6A5B237002FB1A0E247F1
02/10/2009 10:36 AM 13,312 _517D39ACB53634B59852C8E153B41E98
02/10/2009 10:35 AM 16,384 _6C0EF8CC468814B88806785D8F531905
02/10/2009 10:35 AM 10,240 _7D696D868B909DC126A1AB2EDED8BEE1
02/10/2009 10:35 AM 10,240 _933F30ADC0DFD69EB551623235879B21
02/10/2009 10:36 AM 14,336 _C91E465D8BB437D741ED4B41A36F6385
9 File(s) 96,046 bytes

Total Files Listed:
17 File(s) 931,555 bytes
11 Dir(s) 18,724,569,088 bytes free

C:\tmp\1 Day\WiX>

The Files under Binary\File are the actual DLL’s etc that have been packaged up and as such can be safely disposed of (we have the originals still available to us within the VS Solution. Binary\Binary contains the various support files that are required to run the installer. Note that the files have no extension – that’s perfectly fine and can be left as is.

Step 2: Create a new WiX project in the solution.

WiX comes with a few bonus tracks; one of which is Votive. Votive is essentially a WiX project type for Visual Studio and gives you not only the ability to edit the files utilizing IntelliSense, but to set up project properties as well.

image

Once built, you should see something akin to the following in your Solution Explorer window:

image

First thing we need to do is gut the created Product.Wxs and replace it with the one Dark.exe generated for us. Make sure the Product.Wxs file is open in the VS Editor then paste the text straight in, overwriting everything.

Step 3: Update the support binaries

If you examine the newly pasted content you’ll come across the first area that we need to address; the support files are currently in the wrong location.

image

To resolve this, create a new Binary folder in the project and copy the contents Binary\Binary folder over to the solution then update the SourceFile values accordingly:

image

Step 4: Update the package files

We’re getting close now – however we still don’t yet have something that will build correctly for the simple reason the references are shot. So they will need to be updated next.

Take a look further down the Wxs file and you’ll come across the area of concern:

image

You’ll notice that the Source value is set to a GUID that refers back to one of the files we threw away after executing Dark.exe. Fortunately we don’t need to translate the filename as it’s provided for us is the Name value. All we need to do here then is replace the folder name and file with a relative path where we’re taking the files from. In my case here I stored the DLL’s used in a folder called Common\Bin. So one of my entries would now look like:

image

Step 5: Referencing external libraries

That takes care of our files, but what of other external files – in my case use of the Enterprise Application Block. In order to make the build transparent across both Visual Studio and TFS I needed a better route of referencing the correct binaries. This is where the use of a Preprocessor directive comes into play.

Open up the WiX project properties and select the ‘All Configurations’ configuration:

image

The Enterprise Application 4.1 block always installs itself into %ProgramFiles\Microsoft Enterprise Library 4.1 – October 2008 so we can use that to create our variable. Enter the following in the first text box (Preprocessor variables):

MSEntBlock41=$(ProgramFiles)\Microsoft Enterprise Library 4.1 – October 2008\Bin

Since VS 2008 (like 2005) uses MSBuild behind the scenes, this will expand to reference the correct location. By using an environment variable we avoid situations where the C: drive may not the the default drive on the build server.

Now we need to simply reference this Preprocessor variable in the Wxs script using the form $(var.MSEntBlock41):

image

Step 6: Dealing with the registry

Whilst the Wxs generated by Dark.exe is valid, it apparently does not meet it’s own standards – namely registry access.

For example, here’s what Dark.exe generated:

image

However the correct format required is:

image

Notice the use of a referencing the windir environment variable. We could have used a Preprocessor variable here as well – I simply wanted to demonstrate using both sorts.

Step 7: App.Config

The final change we need to make is to reference the applications App.config file. Normally the deployment project handles this transformation for us but we need to perform the step via WiX. However it’s easy enough:

image

Step 8: Updating the build configuration

The final step required is to ensure TFS Build picks up the new project. The set up projects created by WiX seem to target Chipsets; as a result I had to update the Configuration Manager to ensure that they were included in a ‘Any CPU’ build. This is probably not best practice but will work for me (your mileage may vary)

image 

Further reading:

WiX Tutorial : http://www.tramontana.co.hu/wix/

Preprocessor variables: http://wix.sourceforge.net/manual-wix2/preprocessor.htm

WiX v3.4805.0, TFS 2008 SP1, VS 2008 SP1

Categories: Code, Visual Studio, WiX
Follow

Get every new post delivered to your Inbox.