Windows Installer 4.5 is now available!!!!!!

Sorry for the belated notice, this was turned loose on 6/3/08.   Great news!!!!
 
Windows Installer 4.5 is now available!!!!!!
 
New and improved features in Windows Installer 4.5:
     The following new and improved features have been implemented in Windows Installer 4.5.
 
Multiple package transaction
In a multiple package transaction, you can create a single transaction from multiple packages. In a multiple package transaction, a chainer is used to dynamically include packages in the transaction. If one or more of the packages do not install as expected, you can roll back the installation.
Embedded UI handler
You can embed a custom user interface (UI) handler in the Windows Installer package. This makes a custom UI easier to integrate. You can also invoke an embedded UI handler from the Add or Remove Programs item in Control Panel. Or, you can invoke an embedded UI handler during a Windows Installer repair process.
 
Embedded chainer
You can use the embedded chainer to add packages to a multiple package transaction. You can use an embedded chainer to enable installation events across multiple packages. For example, you can enable install-on-demand events, repair events, and uninstall events across multiple packages.
 
Update supersedence resiliency
This feature lets you correct for changes in the FeatureComponent table during supersedence.
 
Shared component patching resiliency during uninstall
This feature makes sure that the most recent version of a component is available to all products.
 
Custom action execution on update uninstall
This feature lets an update add or change a custom action so that the custom action is called when an update is uninstalled.
For more information you can check the MSDN Documentation or the Windows 4.5 Installer Team Blog.
 
 
Posted in Development | Leave a comment

Windows 2008, the new Windows Mobile Center & Windows Mobile 6

On the 64-bit platform, these work great together.  The new UI is great and (at least for me) the sync’ing was much better than under the old platform and software.  However, there is a major gotcha that you should watch out for.  If you install and sync under the old versions (ActiveSync & Mobile 5.x) then upgrade, be aware that if it asks you to add a new partnership for the device, “just say no”.  Otherwise, WMC (Windows Mobile Center) will not recognize your device.  Uninstalling everything and re-installing will not resolve the issue.  If I find a workaround, I’ll share it with the group but so far all efforts have not had any effect.

 

 

Posted in Computers and Internet | Leave a comment

Windows 2008 continued

Oh and I forgot one more thing.  On my new machine (Dell Precision T5400), when I installed 64-bit Windows 2008, I could no longer use the DVD-RW.  It just wouldn’t recognize any disk I put in.  But I found a great work-around until they get that worked out.  You can use "CD-Burner-XP" to burn CDs, DVDs, *RWs, … It works quite well, no matter how many bits or which OS!
 
Happy Coding!!!
 
Posted in Development | Leave a comment

Windows 2008 & Hyper-V

OK, I was yet another one that ran straight into the Windows 2008 brick wall.  Lots of stuff didn’t work right out of the gate, lots of things to adjust and the one thing that I had been drooling for (Hyper-V) was just plain bitting me in the arse!!!
 
That has changed.  I’m absolutely very PRO Windows 2008 Server!!!!   It took some time (like I should have expected) to get things back on track.  There are still some things to fix but I’m getting there.  Hyper-V can be pretty frustrating at first until you figure out some of the tricks.
 
One trick that I found was that no matter what I did, I couldn’t get the VMs to recognize the network card.  It was Broadcom NetXtreme Gigabit Ethernet card.  That’s a very well known brand with great drivers.  But the dern VM just didn’t want to recognize it.  Then I looked at the settings and found the "Legacy Network Adapter" option.  Once I used that, BAMMO! I was off and running! 
 
Windows 2008 is fast, stable and sweet!   I highly recommend it for everything, including desktop OS.  The reason I say that is that you can pretty much transform your Server OS desktop into a Vista Workstation desktop with the following tricks:
 
Now I have the best of both worlds on one desktop!!!!
 
Happy Coding!
Posted in Virtualization | Leave a comment

Cool SQL 2005 Tool!

This is soooooo cool!!!!
 

TableDiff.exe

Table Difference tool allows you to discover and reconcile differences between a source and destination table or a view. Tablediff Utility can report differences on schema and data. The most popular feature of tablediff is the fact that it can generate a script that you can run on the destination that will reconcile differences between the tables. TableDiff.exe takes 2 sets of input;

Connectivity – Provide source and destination objects and connectivity information.

Compare Options – Select one of the compare options

Compare schemas: Regular or Strict

Compare using Rowcounts, Hashes or Column comparisons

Generate difference scripts with I/U/D statements to synchronize destination to the source.

TableDiff was intended for replication but can easily apply to any scenario where you need to compare data and schema.

You can find more information about command line utilities and the Tablediff Utility in Books Online for SQL Server 2005.

 

How can you not get excited about this kinda stuff?!?!?!?!?!???

 

Posted in Development | Leave a comment

And over the XML we go…

Feeling like Homer Simpson…

Sorry for being out of touch for so long.  We had to get ready for beta in a foreign country and we’re rocking and rolling toward full production.  (I now have less hair!)  It’s all fun, but I had an issue that came up and the MSDN forums indicated it could be a duplicate Project GUID.   Since we create our own project files (we have special needs J), I thought that was very possible.  So in 15 minutes, I threw together a utility that would walk every directory and read every project file and look for duplicates.  Seemed simple enough, however, my

DocumentElement.SelectSingleNode("//Project/PropertyGroup/ProjectGuid")

was always returning null!

 

The project file was simple enough:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003&quot; ToolsVersion="2.0">

  <PropertyGroup>

    <BinplaceToBinariesFolder>true</BinplaceToBinariesFolder>

    <BinplaceToSymbolsFolder>true</BinplaceToSymbolsFolder>

  </PropertyGroup>

  <Import Project="$(NTMAKEENV)My.Build.settings" />

  <PropertyGroup>

    <ProjectGuid>{71440C14-ED89-4FF0-B1EF-3A217CC6887D}</ProjectGuid>

    <OutputType>library</OutputType>

    <RootNamespace>My.Namespace.MyAssembly</RootNamespace>

    <AssemblyName>MyAssembly</AssemblyName>

    <SignAssembly>true</SignAssembly>

    <AssemblyOriginatorKeyFile>….My.snk</AssemblyOriginatorKeyFile>

    <StyleCopEnabled>true</StyleCopEnabled>

    <DocumentationFile>$(IntermediateOutputPath)$(AssemblyName).xml</DocumentationFile>

  </PropertyGroup>

                        … rest goes here …

</Project>

 

And the code to retrieve the ProjectGuid was simple enough as well:

// Load the project file

                        XmlDocument doc = new XmlDocument();

                        doc.Load(fileName);

                        // retrieve the Project Guid

                        XmlNode node = doc.DocumentElement.SelectSingleNode("//Project/PropertyGroup/ProjectGuid");

                        // do something here . . .

 

OK, I thought, I’m a smart guy, I know it’s a namespace problem.  I can see in the project that there is a default namespace and according to the MSDN documentation for XmlNamespaceManager, to make a default namespace you use:

String.Empty

The empty namespace. This value can be assigned to a prefix. For example, xmlns="" defines the default namespace to be the empty namespace.

 

So I updated the code as follows:

// Load the project file

                        XmlDocument doc = new XmlDocument();

                        doc.Load(fileName);

                        // create a default namespace

                        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

                        nsmgr.AddNamespace("", "http://schemas.microsoft.com/developer/msbuild/2003&quot;);

                        // get the Project Guid

                        XmlNode node = doc.DocumentElement.SelectSingleNode("//Project/PropertyGroup/ProjectGuid", nsmgr);

                        // do something here . . .

 

But still nothing!  Thanks to a co-worker who whacked me in the back of the head saying “We dealt with this before” (to be honest, he had forgotten at first too!).   The docs are incorrect when using a default namespace.  You do have to give it a prefix.  So the correct code was:

                        // Load the project file

                        XmlDocument doc = new XmlDocument();

                        doc.Load(fileName);

                        // create a default namespace

                        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

                        nsmgr.AddNamespace("a", "http://schemas.microsoft.com/developer/msbuild/2003&quot;);

                        // get the Project Guid

                        XmlNode node = doc.DocumentElement.SelectSingleNode("//a:Project/a:PropertyGroup/a:ProjectGuid", nsmgr);

 

Now this is all fine and dandy and I’m glad I had it re-implanted into my brain cells.  However, it’s not all that performant.  Now, for what I was doing (building a utility), it didn’t matter as much, but for production quality code, performance does matter.  One of the reasons it’s not too speedy is that it loads the XML into the DOM.  To use an XmlReader, we could use the code below:

 

                        // create a reader

                        XmlTextReader xmlReader = new XmlTextReader(fileName);

                        // read until…

                        while (xmlReader.Read())

                        {

                                                switch (xmlReader.NodeType)

                                                {

                                                                        // use the NodeType to look for an element

                                                                        case XmlNodeType.Element:

                                                                                                // we find an element named "ProjectGuid"

                                                                                                if (xmlReader.Name == "ProjectGuid")

                                                                                                {

                                                                                                                        // use xmlReader.ReadString() to get the value of the element

                                                                                               

                                                                                                                        // do something here

                                                                                                }

                                                                                                break;

                                                                        }

                                                }

                        }

 

 

Pretty simple stuff, but yet can trip you up and make you waste time (which none of us have enough of!).

 

Hope that helps and happy coding!

 

 

Posted in Uncategorized | Leave a comment

RE: The shocking truth about the C# lock statement

OK, so my example was a bit contrived.  In most cases what we do in our critical sections would be more than just adding to a List<>.  And in those cases, if an exception is thrown, we would hold the lock.   The next thought that came from that was that if you use an established pattern (lock), then why mix?   I believe that you should use the right tool for the right job.   I will have to chew on this more before I acquiesce on this point, however.   I would like to hear other opinions.

Posted in Performance | Leave a comment

The shocking truth about the C# lock statement!

In delving deep into C#, the CLR, IL and what really happens under the hood, I’ve discovered a shocking truth about the commonly used lock statement.  Everyone knows that when it’s compiled the lock statement actually uses a light weight Monitor object to handle the lock, but what you might not know (and I didn’t) was that it also throws in a try/finally in there for good measure.

Consider the following the following method that uses the lock statement:

 

                        public void UsingLock(List<string> mystuff, string value)

                        {

                                    lock (mystuff)

                                    {

                                                mystuff.Add(value);

                                    }

                        }

 

Nothing too terribly exciting, but it is common.  This method gets compiled down to the following IL:

 

.method public hidebysig instance void  UsingLock(class [mscorlib]System.Collections.Generic.List`1<string> mystuff,

                                                  string ‘value’) cil managed

{

  // Code size       25 (0x19)

  .maxstack  2

  .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<string> CS$2$0000)

  IL_0000:  ldarg.1

  IL_0001:  dup

  IL_0002:  stloc.0

  IL_0003:  call       void [mscorlib]System.Threading.Monitor::Enter(object)

  .try

  {

    IL_0008:  ldarg.1

    IL_0009:  ldarg.2

    IL_000a:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)

    IL_000f:  leave.s    IL_0018

  }  // end .try

  finally

  {

    IL_0011:  ldloc.0

    IL_0012:  call       void [mscorlib]System.Threading.Monitor::Exit(object)

    IL_0017:  endfinally

  }  // end handler

  IL_0018:  ret

} // end of method Program::UsingLock

 

You’ll notice the extra try/finally that you didn’t ask for!   Now, since the lock statement uses a Monitor object internally, you would expect the following method to compile down to the same IL:

 

                        public void UsingMonitor(List<string> mystuff, string value)

                        {

                                    Monitor.Enter(mystuff);

                                    mystuff.Add(value);

                                    Monitor.Exit(mystuff);

                        }

 

But as you’ll notice, it doesn’t!  

 

.method public hidebysig instance void  UsingMonitor(class [mscorlib]System.Collections.Generic.List`1<string> mystuff,

                                                     string ‘value’) cil managed

{

  // Code size       20 (0x14)

  .maxstack  8

  IL_0000:  ldarg.1

  IL_0001:  call       void [mscorlib]System.Threading.Monitor::Enter(object)

  IL_0006:  ldarg.1

  IL_0007:  ldarg.2

  IL_0008:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)

  IL_000d:  ldarg.1

  IL_000e:  call       void [mscorlib]System.Threading.Monitor::Exit(object)

  IL_0013:  ret

} // end of method Program::UsingMonitor

 

It results in four less IL statements than in the previous method!  Talk about a waste of cycles!   Now, just think that if this is a method that gets called relatively frequently or possibly many times at one time.   That’s a lot of waste. 

 

Now, I know that some would argue that the lock statement may be more elegant than using the Monitor object, but when it comes to scalability, common sense rules.  Use the Monitor rather than the lock whenever you can.

 

 

Happy Coding!

 

Posted in Performance | Leave a comment

Silverlight 2.0 Beta 1

As you know, Silverlight 2.0 Beta 1 was turned loose on the 5th, but one of the things I didn’t know was that it had Adaptive Streaming – The Silverlight client can adaptively determine the bandwidth between the client and the server and set the bit-rate appropriately. And can change on-the-fly, if necessary.
 
If that’s not exciting, I don’t know what is!!!!!!!!
Posted in Silverlight | Leave a comment

The ‘volitile’ myth

OK, I think I should clarify something about what I said in regards to all of the Microsoft JIT’ed assignments are volatile.   Yes, that is a true statement, but you cannot simply take that out of context and say “Well, then that means that all of my assignments are safe”.  Yes, they will be, but that doesn’t mean that it will operate the way you think it does.  Take for instance the following code snippet:

 

       Char[] cArr = new Char[20];

       public void Func()

       {

              object secondRef = cArr;

              if (secondRef == cArr)

              {

                     if (secondRef == cArr)

                           return;

              }

       }

 

Upon first glance, you might think that, “Well, since my assignments are all volatile, there’s nothing wrong with this code.  The surprise comes in when you look at the JIT’ed IL:

 

        public void Func()

        {

            object secondRef = cArr;

00000000  mov         edx,dword ptr [ecx+4]

00000003  mov         eax,edx

            if (secondRef == cArr)

00000005  cmp         eax,edx

00000007  jne         00000009

00000009  ret    

        }

 

You’ll notice that the code is optimized and stores the first object reference inside a register with the intent of not having to check the memory location subsequent times (this is the optimization).  So now, let’s decorate the array with the volatile keyword.  You immediately notice that the JITer no longer stores any previous addresses of the array inside a register.  Each comparison call will get the array address from memory:

 

        public void Func()

        {

            object secondRef = cArr;

00000000  mov         eax,dword ptr [ecx+4]

            if (secondRef == cArr)

00000003  cmp         eax,dword ptr [ecx+4]

00000006  jne         0000000B

            {

                if( secondRef == cArr )

00000008  cmp         dword ptr [ecx+4],eax

0000000b  ret  

         }

 

 

If you omit the volatile keyword, the second check is simply removed and a register compare is performed with the previously determined address of the array. When you add the volatile keyword the cmd eax,edx becomes cmp eaxdword ptr[ecx+4] which in works like a memory barrier.   So even though Microsoft’s JITer makes every assignment volatile, you HAVE to keep in mind what type of optimizations occur.

Posted in Development | Leave a comment