Vista Defrag Woefully Inadequate - Enter O&O Defrag

Being rather new to Vista this week, I was sorely disappointed to see the severely dumbed down defrag utility in Vista. A pathetic effort. Really! So after a few highly scientific Google searches, I settled on O&O Defrag and could not be happier.

Here's the lame, incredibly useless UI in Vista's Disk Defragmenter. Note, if you are going to use some other defragmenter on a schedule, which I would recommend, be sure to disable the regularly scheduled Vista defragmenter by unchecking the box. One way of getting there is to go to the Control Panel and then Performance Information and Tools and then Advanced Tools.

And here is only part of the incredibly useful O&O Defrag UI, a shot taken as it defrags my drives:

Of course there are other suitable defrag tools such as DiskKeeper and others. Perhaps Microsoft wanted the Vista tool to cater only to the basic, uninformed user. If so, they certainly left the market wide open to the more sophisticated tools vendors such as O&O.

 

From XP Pro to Vista Ultimate x64

I finally took the plunge. Now I get to use 4GB out of 4GB except that the bare minimum I seem to be able to get Vista x64 down to is a 1.2GB footprint. And that's after hours and hours of experimentation and disabling some visual enhancements, though I feel no loss there and am experiencing a significantly reduced sense of loss.

Now I'm happy to be able to test on x64 virtual images using VMWare's Workstation, I'm afraid I may need to buy four 2GB sticks of RAM now. Despite the fact that the additional memory is available now, the larger footprint nearly wipes out the gain.

And that's without running any significant applications, except IE, which is quite a memory hog. I guess the old 640K upper limit days are over.

Yes, RAM is cheap. A quick check on Newegg.com and I found 8GB (4 x 2GB DDR2 800) for $174. I can't even buy three tanks of gas for my SUV for that.

Virtual PC 2007 vs VMWare Workstation 6.5

I'm getting ready to do some serious MOSS 2007 architecture and development work. In the past, I've used Virtual PC 2007 to host a virtual development environment running a Windows server operating system, SQL Server, MOSS and Visual Studio all running in the same virtual machine. And I've never been very happy with the performance of that virtual machine.

So today I decided to give VMWare a try and downloaded VMWare Workstation 6.5. I installed Windows Server 2008 Standard x86 (full install) on a new virtual machine with the same disk space and memory as I had allocated for the same operating system install using Virtual PC 2007. I gave both virtual machines 30GB of disk space and 1GB of RAM. I'm running on a Core 2 Duo 6600 on an ASUS P5B at factory default speed with 4GB of RAM with virtualization support enabled. Both virtual machines virtual drives live on the same drive.

The major advantage of VMWare is its ability to utilize both cores where Virtual PC is stuck with using just one. I'm sure there are additional reasons for the differences in performance. I used PerformanceTest 6.1 from PassMark. I'm sure there are other ways to test virtual machine performance, but this seemed to be a reasonable though unscientific approach. I made sure my machine was running the same processes and completely idle except for the virtual machine host application.

I only ran the tests that mattered to me: CPU, 2D, memory, and disk. I don't care about 3D and CD performance for the virtual machine. Here's the results:

vmware

test 1

test 2

avg

ratio

cpu: 326.6 344.4 335.5 2.2x
2D: 28.7 32.2 30.45 3.3x
Memory: 96.7 96.2 96.45 1.2x
Disk: 469.1 454.5 461.8 6.4x
Total: 921.1 927.3 924.2 2.9x
vpc 2007
cpu: 150.7 154.1 152.4
2D: 9.2 9.3 9.25
Memory: 83.3 83.2 83.25
Disk: 69.6 73.8 71.7
Total: 312.8 320.4 316.6
 

I was amazed to see that overall, the VMWare virtual machine ran 2.9 times faster than the Virtual PC machine. Even more amazing was the performance improvement of the 2D and disk tests, 3.3 and 6.4 times faster respectively.

I am now completely sold on the value of the VMWare Workstation license. The best price I found after a quick search was $161. For all the saved frustration in working with a slow virtual machine development image for MOSS, the product is well worth the price. But don't take my word for it, run your own tests if you don't believe me. Of course, if you aren't running a multicore machine, and what self respecting developer isn't, you probably won't see any improvement. On the other hand, if you have at least two cores, choosing save a few bucks seems to penny wise but pound foolish!

 

MSDN Subscription - Zupancic Heroic MVP

Props, kudos, and thanks a million to my good friend Aaron Zupancic, one of Microsoft's most valuable MVPs. Last week I pinged him to ask his opinion about a site I'd found adversting an VS 2008 Pro MSDN Pro 2 year sub for $999. It was a decent price but the site seemed a bit sketchy. He seemed to agree with my assessment and then asked if I'd like one of the complimentary VSTS 2008 MSDN Premium subscriptions that Microsoft had sent him with his MVP package. Wow!

That's over $10,000 worth of tools!

Thanks ten thousand times over, Aaron! You're awesome!

In exchange, I promise to faithfully attend the Utah user group meetings!

And before you inundate Aaron with begging, let me dispell the rumor that he has an unlimited supply. Aaron gave the other complinetary sub to another friend and user group supporter. And please don't nag him for picking me over you. Blame me, blind luck, and accidentally perfect timing!

ASP.NET MVC Making Web Development Fun Again

I want to thank Scott Guthrie and Scott Hanselman and the whole ASP.NET MVC team for making web development fun again.

The simplicity of Rails, the power of .NET, and so much more. I've been reading the posts and watching some of the screencasts but had not yet tried it for real. That all changed over the weekend while working my latest pet project which I hope to reveal sometime soon. I decided to put MVC Preview 4 to the test. I was not disappointed.

I mean, who could not fall in love with the elegant simplicity of this view?

<tr>
  <td>Current password:</td>
  <td><%= Html.Password("currentPassword") %></td>
</
tr>
<
tr>
  <td>New password:</td>
  <td><%= Html.Password("newPassword") %></td>
</
tr>
<
tr>
  <td>Confirm new password:</td>
  <td><%= Html.Password("confirmPassword") %></td>
</
tr>
<
tr>
  <td></td>
  <td><input type="submit" value="Change Password" /></td>
</
tr>

Handled by this controller:

[Authorize]
public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword)
{

    ViewData["Title"] = "Change Password";
    ViewData["PasswordLength"] = Provider.MinRequiredPasswordLength;

    // Non-POST requests should just display the ChangePassword form
    if (Request.HttpMethod != "POST")
    {
        return View();
    }

    // Basic parameter validation
    List<string> errors = new List<string>();

    if (String.IsNullOrEmpty(currentPassword))
    {
        errors.Add("You must specify a current password.");
    }
    if (newPassword == null || newPassword.Length < Provider.MinRequiredPasswordLength)
    {
        errors.Add(String.Format(CultureInfo.InvariantCulture,
                    "You must specify a new password of {0} or more characters.",
                    Provider.MinRequiredPasswordLength));
    }
    if (!String.Equals(newPassword, confirmPassword, StringComparison.Ordinal))
    {
        errors.Add("The new password and confirmation password do not match.");
    }

    if (errors.Count == 0)
    {

        // Attempt to change password
        MembershipUser currentUser = Provider.GetUser(User.Identity.Name, true /* userIsOnline */);
        bool changeSuccessful = false;
        try
        {
            changeSuccessful = currentUser.ChangePassword(currentPassword, newPassword);
        }
        catch
        {
            // An exception is thrown if the new password does not meet the provider's requirements
        }

        if (changeSuccessful)
        {
            return RedirectToAction("ChangePasswordSuccess");
        }
        else
        {
            errors.Add("The current password is incorrect or the new password is invalid.");
        }
    }

    // If we got this far, something failed, redisplay form
    ViewData["errors"] = errors;
    return View();
}

Yes, you say, but what about all my high powered controls from XYZ Controls Company? Do they really make your life that much easier? Is HTML so hard? Have you looked at your ViewState lately? Yikes! Certainly there are tradeoffs, but you can bet that controls are on their way. Where Microsoft stack developers go, the control vendors soon follow.

Give me clean HTML with CSS style and controllers that support TDD in the most straightforward manner I've ever seen, sprinkle in some convention over configuration jazz from Ruby on Rails, and I'm a happy web developer again after having spent the last four and a half years avoiding ASP.NET while writing back end data and content analysis systems.

ASP.NET never looked better!

 

Some Things are True Whether They are True or Not

I get a lot of forward email from friends and relatives. I've never felt compelled to do anything with any of them until, bored this evening, I read this one from my father-in-law. I don't know if any of these stories are true or not, but whether they are or aren't, they are. In a time when America seems to be taking much criticism from within and without, it's good to have reminders like these.

When in England, at a fairly large conference, Colin Powell was asked by the Archbishop of Canterbury if our plans for Iraq were just an example of empire building by George Bush. He answered by saying, 'Over the years, the United States has sent many of its fine young men and women into great peril to fight for freedom beyond our borders. The only amount of land we have ever asked for in return is enough to bury those that did not return.'

There was a conference in France where a number of international engineers were taking part, including French and American. During a break, one of the French engineers came back into the room saying 'Have you heard the latest dumb stunt Bush has done? He has sent an aircraft carrier to Indonesia to help the tsunami victims. What does he intended to do, bomb them?' A Boeing engineer stood up and replied quietly. 'Our carriers have three hospitals on board that can treat several hundred people; they are nuclear powered and can supply emergency electrical power to shore facilities; they have three cafeterias with the capacity to feed 3,000 people three meals a day, they can produce several thousand gallons of fresh water from sea water each day, and they carry half a dozen helicopters for use in transporting victims and injured to and from their flight deck. We have eleven such ships, how many does FRANCE HAVE?'

A U.S. Navy Admiral was attending a naval conference that included Admirals from the U.S., English, Canadian, Australian and French Navies. At a cocktail reception, he found himself standing with a large group of Officers that included personnel from most of those countries. Everyone was chatting away in English as they sipped their drinks but a French admiral suddenly complained that, whereas Europeans learn many languages, Americans learn only English. He then asked, 'Why is it that we always have to speak English in these conferences rather than speaking French?' Without hesitating, the American Admiral replied "maybe it's because the Brits, Canadians, Aussies and Americans arranged it so you wouldn't have to speak German.'

An elderly American gentleman of 83, arrived in Paris by plane. At French Customs, he took a few minutes to locate his passport in his carry on. 'You have been to France before, monsieur?' the customs officer asked sarcastically. The man admitted that he had been to France previously. 'Then you should know enough to have your passport ready.' The American said, 'The last time I was here, I didn't have to show it. 'Impossible. Americans always have to show your passports on arrival in France !' The American senior gave the Frenchman a long hard look. Then he quietly explained, 'Well, when I came ashore at Omaha Beach on D-Day in 1944 to help liberate this country, I couldn't find a single Frenchmen to show a passport to.'

Serenity and Leukemia: An Angel's Battle with Cancer

One of my very best friends, Phil Burns, whom I love like a brother, called me Friday afternoon. But it wasn't him.

It was his phone but I did not recognize the voice on the phone. The voice belonged to a woman whom I assume was a hospital emergency room employee. She informed me that Phil's wife Adria was boarding an ambulance with their 22 month old daughter Serenity to be transported from the American Fork Hospital to the Primary Childrens Hospital in Salt Lake City. I asked what was wrong and she told me that Serenity was very sick and may have leukemia.

I was stunned. I told her to let Phil know I'd be in touch very soon or to call me when he was able with more news. I cut short a business lunch and walked back to the office from the food court and let my boss know that I'd be gone the rest of the afternoon. On the way home, Phil called me and was very upset. He told me some of the story that you can find on his blog.

Between sobs of grief and fear, Phil begain to tell me the story. His tiny little angel named Serenity, not yet two years old, was on her way to the best childrens hospital in the intermountain west. A helicopter was on standby in case her breathing became more shallow. Phil was on his way home to pick up some things for a hospital stay that he was told would be at least three or more days. I told him I'd meet him there.

Serenity is the very definition of purity and beauty. Here large brown eyes, which you can see here on a site that a friend has put together, can melt your heart and make you want to do anything you can to alleviate her suffering.

The good news is that her prognosis is very hopeful but she will have to go through a lot to get there. She will get through it with a mountain of love and sea of patience from her parents and family and friends. But it will take one more thing: a Greengotts vault full of gold. The Burns family has no health insurance. And the hospital calls leukemia babies "Million Dollar Babies." The Burns family will need every bit of assistance we can give them. You and I can help. A donation account has been setup. Please open your wallet as far as this bright little angel can open your heart. If you have the courage to look into her eyes and wonder what the rest of her life holds in store, opening your wallet to help with the bills will be something you cannot avoid.

Windows Form Talks to Windows Service via WCF without Config File

I am fascinated with Windows Communication Foundation (WCF) but the configuration files can be cumbersome. Until now I haven't had the time to investigate programmatic configuration of WCF, but I may be involved in a project soon in which WCF would be useful but where configuration files would present an unnecessary complication to the end user. So I've spent some time researching and experimenting. To my happy surprise, WCF is easily configured programmatically. A little research has resulted in a simple Windows Forms application talking to a Windows Service via WCF while both client and server use a common class library that defines the service contract and data transfer objects. I'll give you a brief overview and then you can download the solution here.

First let me give credit where credit is due. I could not have figured out all of this stuff without the great help of Juval Lowy and his book Programming WCF Services. I highly recommend the book. I also took advantage of some of the samples published on his http://www.idesign.net/ web site. If you need help with your WCF work, I urge you to contact them.

You download the entire solution at the bottom of this entry, so I'm not going to push all the code into the text here, but I'll try to cover the highlights.

Framework/Architecture
The architecture of this little test application is simple.

  • MyWcfService - (server) A Windows service application
  • MyWcfMon - (client) A Windows Forms application with a simplistic test
  • MyWcfLib - A class library defining the service contract used by client and server

MyWcfLib
Since I like the "contract first" approach, let's begin with the interface and data transfer objects shared by client and server. This is a very simple piece of code but sufficient to illustrate the principles involved (see IMyWcfServiceControl.cs).

[ServiceContract]
public interface IMyWcfServiceControl
{
    [OperationContract]
    MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command);
}

[DataContract]
public class MyWcfServiceCommand
{
    [DataMember]
    public string Command { get; set; }
}

[DataContract]
public class MyWcfServiceResponse
{
    [DataMember]
    public string Response { get; set; }
}

As you can see, we have a simple service contract with a single operation and a simple command object taken and response object returned.

You'll also notice an Extensions.cs file in the MyWcfLib project. These are a few of my favorite extensions I've written lately. I find them very useful but they are not terribly relevant to this project. You can take a look at them later in the source download.

MyWcfService
I won't bore you with the details of the Windows service code, though I do encourage you to download the code and give it a look. I've blogged about this before but it's worth metioning, if only for the keyword exposure. The service code allows you to debug the service as a console application and then compile in "Release" and deploy/install as a real Windows service. A handy little chunk of code.

The primary area of interest in the service is the declaration of the WCF ServiceHost and how it is configured in code. In the following lines of code found in the MyWcfService.cs file in the project, we create a WCF host listening on a port configured using the m_port value, requiring Windows authentication and using encryption and message signing on the transport layer. Fast but highly secure.

Uri tcpBaseAddress = new Uri(string.Format("net.tcp://localhost:{0}/", m_port));
serviceHost = new ServiceHost(typeof(MyWcfServer), tcpBaseAddress);

NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

serviceHost.AddServiceEndpoint(typeof(IMyWcfServiceControl), tcpBinding,
    string.Format("net.tcp://localhost:{0}/MyWcfServiceControl", m_port));

//this is the default but good to know
serviceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseWindowsGroups;

serviceHost.Open();

That's it. We're now configured. Not so hard. Not really any more difficult than raw .NET remoting configuration. In fact, probably easier.

Of course, the Stop method on the ServiceRunner class executes the Close method on the service host.

Now to the implementation of the IMyWcfServiceControl interface in the MyWcfServer.cs file:

internal class MyWcfServer : IMyWcfServiceControl
{
    [PrincipalPermission(SecurityAction.Demand, Role = @"nbdev2\allwcfgroup")]
    [PrincipalPermission(SecurityAction.Demand, Role = @"nbdev2\mywcfgroup")]
    public MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
    {
        MyWcfServiceResponse response = null;
        if (IsAuthorized())
        {
            response = new MyWcfServiceResponse()
            {
                Response = command.Command + " response " + DateTime.Now.ToLongTimeString()
            };
        }
        else
        {
            response = new MyWcfServiceResponse()
            {
                Response = "Error: user not authorized"
            };
        }
        return response;
    }

    bool IsAuthorized()
    {
        //The PrincipalPermission attributes are an OR proposition.
        //The following enforces the AND requirement.
        IPrincipal p = Thread.CurrentPrincipal;
        if (p.IsInRole(@"nbdev2\allwcfgroup") && p.IsInRole(@"nbdev2\mywcfgroup"))
            return true;
        else
            return false;
    }
}

Note that we have two layers of security authorization employed here. (Authentication has already been handled automatically for us.) First we have two PrincipalPermission attributes that demand that the user be in one of two groups. But in fact, our invented requirement here is that the user belong to both groups. Don't ask me why. It's a demo.

So the IsAuthorized method is called and there we examine the Thread.CurrentPrincipal to learn if the requirement is met. This was a revelation to me. I did not know that the thread handling the single call to the WCF service would be running under the calling user context. A very good thing to know. Note to self...

MyWcfMon
Now to the client. It's simple really, and you could probably find an even more clever way to write it, but this might help you get started. You will find in the source a file called MyWcfServiceProxy.cs where the following code lives in the MyWcfServiceProxy class:

internal MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
{
    NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
    tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
    tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

    EndpointAddress endpointAddress =
        new EndpointAddress(string.Format("net.tcp://{0}:{1}/MyWcfServiceControl", m_server, m_port));
    
    MyWcfServiceControlClient proxy = new MyWcfServiceControlClient(tcpBinding, endpointAddress);

    //Note: current user credentials are used unless we use runtime provided credentials like this
    NetworkCredential credentials = new NetworkCredential(m_userName, m_password);
    if (m_domain != null) credentials = new NetworkCredential(m_userName, m_password, m_domain);
    proxy.ClientCredentials.Windows.ClientCredential = credentials;
    
    MyWcfServiceResponse response = proxy.ExecuteCommand(command);
    
    //if proxy is in Faulted state, Close throws CommunicationObjectFaultedException
    if (proxy.State != CommunicationState.Faulted) proxy.Close();

    return response;
}

class MyWcfServiceControlClient : ClientBase<IMyWcfServiceControl>, IMyWcfServiceControl
{
    public MyWcfServiceControlClient(Binding binding, EndpointAddress address) : base(binding, address) { }
    public MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
    {
        MyWcfServiceResponse response = null;
        try
        {
            response = Channel.ExecuteCommand(command);
        }
        catch (SecurityNegotiationException ne)
        {
            response = new MyWcfServiceResponse() { Response = ne.Message };
        }
        catch (SecurityAccessDeniedException ae)
        {
            response = new MyWcfServiceResponse() { Response = ae.Message };
        }
        return response;
    }
}

The WCF client is easily configured programmatically as you can see. Create a Binding, an EndpointAddress, a NetworkCredential if you want to, and then call the service. The private MyWcfServiceControlClient class just makes it a little easier to isolate the configuration code in the code above it.

So now, we have a simple Form that does this:

string userName = txtUserName.Text;
string password = txtPassword.Text;
MyWcfServiceProxy sp = new MyWcfServiceProxy("localhost", 8239, userName, password, null);
MyWcfServiceCommand command = new MyWcfServiceCommand()
{
    Command = "Hello world."
};
MyWcfServiceResponse response = sp.ExecuteCommand(command);
lblTest.Text = response.Response;

With this little framework, you can extend the command and response classes and build pretty much anything you want between your Windows Forms application and your Windows service with the comfort of secure, encrypted and signed communication between the two on the port of your choice.

If you find this useful, I'd love to hear about it. The code can be found here MyWcfService.zip (31.6KB) under the MIT license. Enjoy!