August 2006 - Posts

 

TechEd 2006 Europe comes closer and closer, so it's time to start blogging about this event isn't it? This year's edition will take place in sunny Barcelona from 7 to 10 November 2006. So what's up this year?

8 technical tracks + 3 virtual tracks

As usual, technical (Microsoft) conferences are divided into several tracks. This year's tracks include:

  • Architecture (ARC) - The right track if you keep yourself busy with software architecture and want to learn more about patterns and practices, modern paradigms (such as SOA), and more stuff like that. This year a brand new competition will be held, called the Iron Architects, where attendees can work in groups and make an architectural proposal for a real-life software scenario.
  • Base Framework (BCL) - Let's just call it System.*. Learn about technologies such as ADO.NET, socket programming, multithreading and the new LINQ technologies. If you're a developer this track will be of high interest to you in order to learn more about the powerful APIs that .NET consists of. (Btw: Did you know BCL also stands for Blood Cholesterol Lowering or short: Becel? Only applicable to Benelux folks...)
  • Connected Systems (CTS) - Today's software products rely on distributed computing a lot. In the world of web services and SOA, a dedicated track to connected systems is just a must have. You'll learn about a wide range of technologies including Web Services Enhancements (WSE) 3.0, .NET Enterprise Services (COM+), the existing APIs in .NET Framework 2.0 but also the new exciting Windows Communication Foundation (WCF aka "Indigo"), Windows Workflow Foundation (WF) and Windows CardSpace (WCS aka "InfoCard"). Next to programming APIs, server products like BizTalk Server 2006 and Host Integration Server 2004.
  • Office System (OFF) - Microsoft Office technologies are not just about tools for end users, it's also about extensibility and smart applications that are nested in a familiar environment for your end users and integrate well with Office application data. The next 2007 Microsoft Office System is what's this track is all about: going from XML file formats, over Office "12" UI development, to Visual Studio Tools for Office and server-side products such as Windows SharePoint Services v3 but also the brand new InfoPath Forms Server and Excel Server. Not to forget about integration with the WinFX (excuse me: .NET Framework 3.0) stack, especially WF.
  • SQL Server (SQL) - You should now by now that SQL Server 2005 is not just about storing and retrieving data, it's about everything which has to do with Business Intelligence including data mining, reporting, programmability ("Gather, Analyse, Report"). So, don't miss out this opportunity to learn about this great technology and to hear it from top speakers like Bob Beauchemin, Kimberly Tripp and Don Vilen.
  • Tools & Languages (TLA) - Express yourself better using code and be more efficient in using the Visual Studio development tools. This track helps you to get a better understanding of language features in VB, C#, C++ but also the upcoming language features in "Orcas" with C# 3.0, VB 9.0 and LINQ. And of course you'll hear about Visual Studio 2005 Team System and Team Foundation Server too.
  • Windows Desktop & Mobile Development (WDM) - Vista is in the air and so is Windows Presentation Foundation (WPF aka "Avalon"). So, WPF will certainly be part of this track, but so is Windows Forms 2.0 programming and Windows Mobile development too. So, if you're in charge of creating an appealing end-user experience, this track is right for you.
  • Web Development (WEB) - In the era of "Web 2.0" a dedicated web track is another must. Technologies that this track focuses on include ASP.NET 2.0, "Atlas" (the AJAX technology extension for ASP.NET 2.0), Windows SharePoint Services and of course the IIS webserver software. Furthermore you'll learn how to create a great cross-browser experience and see how Internet Explorer 7 has better support for standards.

But there's more. There are many roads to take when it comes down in dividing sessions into tracks (see Hans' post on this issue). So there are 3 virtual tracks too:

  • Business Intelligence (BI) - This track covers everything around BI in various products, including the 2007 Microsoft Office System, SQL Server 2005, SharePoint technologies, Microsoft Office Business Scorecard Manager 2005, etc.
  • Security (SEC) - Trustworthy Computing, the Security Development Lifecycle (SDL), ... it's all about security. In today's connected world, security is a key concept that should be thought about from day -1 in the creation of a product. This virtual track focuses on various concepts related to security that should aid you in creating secure software that's ready to hit the roads where internet worms are crossing, hackers are ahead and viruses spoil the (once so fresh?) internet air. Don't miss these sessions and learn about Vista's new security features too.
  • WinFX (WFX) - Should be called .NET Framework 3.0 now but you know what I'm talking about. This track brings together sessions on Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF), Windows Workflow Foundation (WF) and Windows CardSpace (WCS).

I agree, choice will be difficult once more but the session search tool will help you out. And if that's not enough yet, there will be the post-conference DVD of course.

Great speakers

The list is just ot long to put it over here, but names like Kimberly Tripp, Bob Beauchemin, Anders Hejlsberg, Ingo Rammer, Clemens Vasters, David Chappell, Christian Weyer, Keith Brown and much more should ring a bell.

And there's more: enter Speaker Idol, a new competition for those of you who want to become a speaker on TechEd. More information about this competetion can be found over here.

Pre-conference sessions

If you just want to sit down and dive deep into a specific technology, the pre-conference sessions on Monday 6 November 2006 will be something for you. For just € 250 you'll get the opportunity to hear about the following technologies from world-class technology experts:

  • Agile Development with Team System (Roy Osherhove) - Learn about unit testing, test driven development, refactoring and other agile principles supported by Visual Studio 2005 Team System.
  • ASP.NET, AJAX and You: Introducing Microsoft Atlas (Jeff Prosise) - See what AJAX is all about and more important how you can use these technologies to create better web applications using ASP.NET 2.0.
  • Developing Solutions with Windows SharePoint Services v3 (Ted Pattison and Patrick Tisseghem) - Build great applications using WSS 3.0. You'll learn about WSS 3.0, Microsoft Office SharePoint Server 2007, .NET 2.0 integration, CAML (Collaborative Application Markup Language) and more.
  • Introduction to Software Architecture (Ron Jacobs) - Regardless whether you are an architect already or want to become one in the future, this pre-conference is the ideal place to learn more about software architecture in general.
  • Making the Most of SQL Server 2005: Developing World Class Database Applications (Brian Randell and Kimberly Tripp) - SQL Server 2005 is such a massive release that a pre-conference is certainly well spent. Focusing on SQLCLR, XML integration, service broker, snapshot isolation, indexing, security, caching, SqlClient 2.0 and much much more you'll see how these exciting features will help you to make your applications better. New technologies such as LINQ will deserve attention too. And of course Kimberly will rock your SQL world again :-).
  • Visual Studio Tools for Office (Eric Carter, Mario Szpuszta, Andrew Whitechapel) - Build great Office-integrated applications for Office 2003 using VSTO. Some topics that will be covered include the VSTO architecture, smart documents, security, solution deployment, the programming model of VSTO and working with data and databinding.
  • What's Coming in .NET 3.0 - Full Immersion (Keith Brown, Ian Griffiths, Fritz Onion, Aaron Skonnard) - This full-day workshop covers the four .NET 3.0 pillars: Windows Communication Foundation (WCF), Windows Workflow Foundation (WF), Windows Presentation Foundation (WPF), and Windows CardSpace (formerly InfoCard). Need to say more? The united forces of Pluralsight will guide you through those next-generation cutting edge technologies.
  • Windows Workflow Foundation - Free Workflow Support for Your Applications (Ingo Rammer, Christian Weyer) - See how you can use workflow in your applications to them better, covering human workflow scenarios and application-based workflows. Want to become familiar with the WF APIs and its capabilities: attend this pre-conference!

Submit your blog

Do you have something to say about TechEd too? Want to start blogging about this great conference and to get seen by others? Just submit your blog.

I'll blog more about TechEd later on; in the meantime check out the event website by clicking the image below. Early bird registrations (Save € 300) run till 29 September 2006.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Introduction

Everyone hates applications that get flagged as "Not responding" by Windows. The Vista-approach of blurring the application's image will make experience a bit better (or should I say, I bit less nasty) but it's undoubtly better to avoid running into this situation at all. So certainly you don't want your application to get trapped in this nightmare. For the moment (see previous posts) I'm in the middle of creating an application that can suffer from a lot of delays (in my case by using .NET Remoting resulting in network traffic, but you can think of various other secenarios such as Web Services, SQL Server, long-running calculations, etc). In this post, I'm showing you how to create a responsive Windows Forms 2.0 application using the BackgroundWorker that can survive errors and looks cute while it's working.

Our goal: a responsive dialog

Assume the following dialog: a user enters some information, clicks on some button and the system starts to communicate with a server which might take a few seconds (or longer) to complete. It's not difficult to image exceptions to occur while the system is interacting with the server. So, our mission statement is twofold:

  • Indicate that the system is working while doing the background work, and stay responsive meanwhile.
  • If the background work results in an exception, offer the end user the possibility to retry the operation or to go back to the dialog (maybe to correct settings).

Getting started

Let's create a new Windows Form (2.0) and make it a dialog (FormBorderStyle=FixedDialog, MaximizeBox=MinimizeBox=false, Icon=<something>, StartPosition=CenterParent). Next, add the following controls:

  • ProgressBar - Name=progress, Style=Marquee, Dock=Bottom, Visible=false
  • Panel - Name=panel, Dock=Fill
  • Button - Name=btnStart, Text=Start (inside the panel + set the form's AcceptButton property to btnStart afterwards)

Next, add some controls to the panel according to the dialog's specification. In my case, I'm just going to create a simple demo application which looks as follows in VS 2005:

The BackgroundWorker

Now it's time to add the BackgroundWorker component (see Toolbox, section Components) to the Windows Form and call it worker:

Go to the events section in the worker's properties and add an event handler (= double click) for DoWork and RunWorkerCompleted). The code will be supplied further on.

Now, how does this new FX 2.0 generation control work? The basic idea is simple: the component allows you to do work in a background thread in an easy and approachable manner. In the past, you had to do the threading manually which could lead to errors, especially when you need to pass information back and forth between the background thread (arguments go in, results go out). The BackgroundWorker helps you to get rid of this plumbing. Let's take a look.

The first thing to do is to start the background thread, typically in a button. So add an event handler for the btnStart_Click event:

private void btnStart_Click(object sender, EventArgs e)
{
   StartWorker();
}

private void
StartWorker()
{
   panel.Enabled =
false
;
   progress.Visible =
true
;
   worker.RunWorkerAsync(
new object[] { decimal
.ToInt32(numSeconds.Value), chkCrash.Checked });
}

This code is pretty straightforward. First we disable the panel because during server interaction the user should not change anything on the input. Next, the progressbar is made visible. By setting the progressbar's Style property to Marquee, the user has the feeling the app is working (just like the little animation when Windows XP and higher are booting - call it an "endless progressbar" if you want). By the way, in Vista such a progressbar looks really flashy :-).

The real work happens in the last line of StartWorker, where we call the RunWorkerAsync method on the BackgroundWorker component. This method takes one parameter as an argument to pass to the background thread. In this case I'm using an object array (you could use a Dictionary or something as well if you want easier lookup-code, see further) which I'm populating with the number of seconds the background job has to run (in reality you don't know this value of course) and a boolean indicating whether I want to simulate a crash inside the worker or not (again, in reality this doesn't make much sense of course). In a real application you'd like to pass the values the user has entered (or some object containing these values).

A question you might ask right now is why you can't just call chkCrash.Checked and numSeconds.Value inside the worker's logic? Simply stated, the answer is you shouldn't call Windows Forms controls inside another thread than the "graphical thread". Furthermore, it makes much more sense too if you look at the BackgroundWorker as kind of a procedural call to do something (and doing that "something" on a different thread, exactly what the BackgroundWorker's encapsulation job is all about). The only thing that makes it a bit more weird-looking than a regular method call is the fact that you have to wrap all parameters into a single object.

So, we've started the background job. Next item on our todo list is to provide an implementation of the background worker's job. This is what the DoWork event was created for:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
   object[] args = e.Argument as object
[];

   Debug.Assert(args != null && args.Length == 2 && args[0] is int && args[1] is bool
);

   int ms = (int)args[0] * 1000;
   bool crash = (bool
)args[1];

   if
(crash)
   {
      Thread
.Sleep(ms / 2);
      throw new InvalidOperationException("Something went wrong."
);
   }
  
else
   {
      Thread.Sleep(ms);
      e.Result =
"Greetings from the worker.";
   }

}

So, what's going on in here. The first line extracts the arguments from the DoWorkEventArgs. This is exactly the same object as the one passed to the RunWorkerAsync method call earlier on. The debugging code is safe to ignore but a real recommendation to keep yourself from making mistakes. Next, the arguments get casted back to the original types (in reality you might consider to create a sort of wrapper type to be strongly-typed from the very beginning). Then comes the real work: what should have been server communication or some other long running job has been replaced in my demo by some Thread.Sleep stuff. In case of a "desired crash", I'm putting the system asleep for half of the specified time and then I'm crashing the worker thread, otherwise I just let it sleep the whole time. Finally, in case of success I'm posting back the result to the caller by setting the Result property of the DoWorkEventArgs argument (once more, in reality you'd likely have a much more complex return type than a string).

Once DoWork completes, either by reaching the end of the method or by throwing an exception, the RunWorkerCompleted event is raised.

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   if (e.Error != null
)
   {
      DialogResult res = MessageBox.Show("The worker has failed. Do you want to try again?\n\nMessage: " + e.Error.Message, this.Text, MessageBoxButtons.YesNo, MessageBoxIcon
.Error);

      if (res == DialogResult
.Yes)
         StartWorker();
      else
         WorkFinished();
   }
   else
   {
      string s = e.Result as string
;
      if (s != null
)
         MessageBox.Show("The worker has completed successfully.\n\nMessage: " + s, this.Text, MessageBoxButtons.OK, MessageBoxIcon
.Information);
      WorkFinished();
   }
}

private void
WorkFinished()
{
   panel.Enabled =
true
;
   progress.Visible =
false
;
}

In this code, we first check for the Error property of the RunWorkerCompletedEventArgs. This property gets populated if the DoWork event handler throws an exception. In case of an error, we present the error message to the end user (together with some friendly text) and ask whether she wants to try to perform the operation again. If nothing went wrong, we just extract the Result from the RunWorkerCompletedEventArgs and present the answer to the end user. In real applications, you can think of a variety of other scenarios such as the e.Result indicating whether something went wrong or not (boolean?).

The result

Below you can see the application in action.

Scenario 1 - Everything goes well

    

Scenario 2 - Oops, error

    

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Introduction

For the moment, I'm working on a thin client project which includes manageability of thin client machines over the network using a so-called "network manager" tool. Technologies involved are .NET 2.0 and .NET Remoting (for various reasons, one of which is to keep the footprint on client machines low).

One of the admin tasks that one has to perform is to shut down a computer remotely (assuming the "administrator" in charge has the right permissions). However, typically such a thing will be done in groups (shut down an entire thin client pc room for instance). The idea is that one single call is made to a server-application to shut down (or reboot or whatever) a list of computers. Once the server gets such a request (and performs the necessairy authentication and authorization), the call is dispatched to all clients but in parallel (a timeout typically takes a couple of seconds, serializing the calls would lead to an enormous wait time).

In this post I'm showing you the pattern of parallel execution of (similar) jobs and how to wait till all of them complete.

The entry point of the parallel job

One of the functions in my code (a bit simplified, i.e. no security or logging code) is:

public Dictionary<string, ManagementResult> Shutdown(string[] computers, TimeSpan delay, string message, bool allowCancel)
{
   if (computers == null
|| computers.Length == 0)
      return new Dictionary<string, ManagementResult
>();

   int
n = computers.Length;

   IAsyncCall[] wos = new ComputerExiter
[n];
   WaitHandle[] whs = new WaitHandle
[n];
   for (int
i = 0; i < n; i++)
   {
      IAsyncCall res = new ComputerExiter(this,
computers[i], delay, message, allowCancel);
      wos[i] = res;
      whs[i] = res.Do();
   }

   WaitHandle.WaitAll(whs);

   Dictionary<string, ManagementResult> results = new Dictionary<string, ManagementResult>();

   foreach (IAsyncCall res in wos)
     
results.Add(res.Computer, res.Result);

   return results;
}

We'll examine this in much more detail further on, but first some groundwork.

The ManagementResult class is a simple multi-property class to report the status of one individual operation. The list of computers goes in, a dictionary mapping the computer name on the result of the desired operation (in this case shutdown) goes out.

[Serializable]
public class
ManagementResult //Implementation omitted for clarity
{
   public ManagementResult(bool success, string message, FailureReason failure, Exception ex);

   public bool Success;
   public Exception
Exception;
   public FailureReason
FailureReason;
   public string
Message;
}

A helper interface and abstract class

Because I have more than one task that has to be executed in parallel, I created a simple helper interface called IAsyncCall:

internal interface IAsyncCall
{
   string Computer { get
; }
  
ManagementResult Result { get
; }
  
WaitHandle
Do();
}

Basically the interface specifies the input (the computer), the output (the result) and the operation itself, returning a WaitHandle. Hang on for a minute to understand the role of the WaitHandle...

About AutoResetEvent and WaitHandle

Next, I have an abstract class implementing this interface, looking as follows:

internal abstract class AsyncCaller : IAsyncCall
{
   protected Management
mgmt;
   protected string
computer;
   protected ManagementResult
result;

   protected AutoResetEvent evt = new AutoResetEvent(false
);

   protected
AsyncCaller(Management mgmt, string computer)
   {
      this
.mgmt = mgmt;
      this
.computer = computer;
   }

   public string
Computer
   {
      get { return
computer; }
   }

   public ManagementResult
Result
   {
      get { return
result; }
   }

   public WaitHandle
Do()
   {
      ThreadPool.QueueUserWorkItem(new WaitCallback
(Helper));
      return
evt;
   }

   public abstract void Helper(object
o);
}

Don't worry about the mgmt variable, this one just keeps a reference to a class of mine that allows to do server-to-client communication and is used to send commands such as "shut down" to an individual computer. The most important part however is the AutoResetEvent. Let's explain:

  • First some information about the class hierarchy: AutoResetEvent inherits from EventWaitHandle which on its turn inherits from WaitHandle.
  • The constructor takes an argument specifying whether the "wait handle" is signaled or not. In this case, we're creating a "wait handle" that is not set (false).
  • Now look at the method Do, which queues the work (using a helper method called "Helper" that has to be implemented in the subclass) using the .NET ThreadPool (you could also use a simple Thread and ThreadStart approach, but using the pool is a better alternative). The Do-method returns the WaitHandle to the caller.
  • The Helper method has a parameter of type object to match the WaitCallback delegate required by the QueueUserWorkItem method of ThreadPool. We are not using the parameter however.

Putting the pieces together

Now we have an abstract class that takes care of some of the plumbing. The next step is to make a concrete implementation:

internal sealed class ComputerExiter : AsyncCaller
{
   private TimeSpan delay;
   private string
message;
   private bool
allowCancel;

   public ComputerExiter(Management mgmt, string computer, TimeSpan delay, string message, bool allowCancel) : base(mgmt, computer)
   {
      this.delay = delay;
      this
.message = message;
      this
.allowCancel = allowCancel;
   }

   protected override void Helper(object
o)
   {
      result =
mgmt.Shutdown(computer, delay, message, allowCancel);
      evt.Set();
   }

}

A few important things to notice:

  • The constructor is straight-forward, just calling the base constructor and setting some fields.
  • The only thing the class does, is implementing the Helper method. Remember that the "object o" parameter is just there to match the WaitCallback delegate. We are not using the parameter however.
  • The Helper method does the dirty work (in this case calling some Management object to perform the shutdown of the one computer that's being processed) but does an even more important thing when it finishes the job: signaling the WaitHandle using evt.Set(). This indicates that work has finished and the system should not longer wait for this thread.

Time to go back to the place we started: our entry-point level method.

Step 1 - Starting the work

Let's start with the first part:

   IAsyncCall[] wos = new ComputerExiter[n];
   WaitHandle[] whs = new WaitHandle
[n];
   for (int
i = 0; i < n; i++)
   {
      IAsyncCall res = new ComputerExiter(this,
computers[i], delay, message, allowCancel);
      wos[i] = res;
      whs[i] = res.Do();
   }

To start with, the code creates a ComputerExiter instance for each computer that has to be shut down. Remember that the ComputerExiter derives from AsyncCaller, which implements IAsyncCall:

      IAsyncCall res = new ComputerExiter(this, computers[i], delay, message, allowCancel);
      wos[i] = res;

Nothing special has happened so far, we've just created an object that holds some info about the job to be done: the computer's name, the shutdown delay, a message to be displayed to the end-user, and a flag indicating whether the end-user can cancel the shutdown operation or not. Finally, we store the object in an array because we'll need it later on (when the job is completed) to gather information about the result using the IAsyncCall.Result property.

Next, it's time to start the ComputerExiter by calling the Do method. This method returns a WaitHandle which we keep in an array (see further):

      whs[i] = res.Do();

Recall the Do method is defined on the abstract AsyncCaller class and does this:

public WaitHandle Do()
{
   ThreadPool.QueueUserWorkItem(new WaitCallback
(Helper));
   return
evt;
}

So, we start running the Helper method on another thread and return the evt object (the AutoResetEvent) to the caller.

Step 2 - Waiting till all work is done

On to the next step: waiting for work to be completed. This is one of the most crucial parts of the code, but also one of the easiest:

   WaitHandle.WaitAll(whs);

Using the WaitAll method call we ask the system to wait till all the WaitHandles have been signaled. Recall that the WaitHandles are initally not signaled (new AutoResetEvent(false)) and that the helper method does the signaling when work has been done (evt.Set()).

 Step 3 - Gathering results

And finally, we can retrieve the results from all individual workers using the Result property defined on the IAsyncCall interface:

   Dictionary<string, ManagementResult> results = new Dictionary<string, ManagementResult>();

   foreach (IAsyncCall res in
wos)
     
results.Add(res.Computer, res.Result);

   return
results;

Wrap up

At the heart of this mechanism are two classes: the AutoResetEvent and the WaitHandle (actually each AutoResetEvent is a WaitHandle). The basic idea is signaling. Using WaitHandle.WaitAll (passing in an array of WaitHandles) you let a thread wait till every WaitHandle has been signaled, which can be done on another thread. Each worker object creates an AutoResetEvent (initally unsignaled) and returns it to the caller. You can see this as the first phase of gathering WaitHandles. Next, the workers can start their mission (each on a separate thread). When a worker completes, it signals the associated WaitHandle. Once all workers have done their jobs, the WaitAll call returns.

Reference sample

Below you'll find a simple Notepad-written reference sample that illustrates the concepts in a clear fashion:

using System;
using
System.Threading;

class
WaitHandleDemo
{
   static int
min = 1;
   static int
max = 9;

   public static void
Main()
   {
      Random rand = new Random
();

      int n = 10;
      WaitHandle[] whs = new WaitHandle
[n];

      for (int
i = 0; i < n; i++)
         whs[i] =
new
Worker(i, rand.Next(min, max) * 1000).Do();

     
WaitHandle
.WaitAll(whs);
   }

   class
Worker
   {
     
private AutoResetEvent evt = new AutoResetEvent(false
);
     
private int
ms;
      private int
i;

      public Worker(int i, int ms
)
      {
         this
.ms = ms;
         this
.i = i;
      }

      public WaitHandle
Do()
      {
         ThreadPool.QueueUserWorkItem(new WaitCallback
(Helper));
         return
evt;
      }

      void Helper(object
o)
      {
         Console.WriteLine("Worker {0} started ({1} ms)."
, i, ms);
         Thread
.Sleep(ms);
         evt.Set();
         Console.WriteLine("Worker {0} stopped."
, i);
      }
   }
}

Output should look like:

Worker 0 started (2000 ms).
Worker 1 started (3000 ms).
Worker 2 started (6000 ms).
Worker 3 started (8000 ms).
Worker 0 stopped.
Worker 4 started (8000 ms).
Worker 5 started (1000 ms).
Worker 6 started (3000 ms).
Worker 1 stopped.
Worker 7 started (5000 ms).
Worker 8 started (1000 ms).
Worker 5 stopped.
Worker 9 started (5000 ms).
Worker 8 stopped.
Worker 6 stopped.
Worker 2 stopped.
Worker 9 stopped.
Worker 7 stopped.
Worker 3 stopped.
Worker 4 stopped.

Enjoy!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Some time ago I wrote about a C# application to perform Wake-on-LAN. Of course there's one additional need in order to get this to work properly: a way to obtain the computers' MAC addresses in order to be able to construct the WOL package. The code below shows how to do this:

ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");

List<Adapter> adapters = new List<Adapter>();

foreach
(ManagementObject mo in query.Get())
   
if ((bool) mo["IPEnabled"] && mo["MacAddress"] != null)
      adapters.Add(
new Adapter((string) mo["Description"], (string) mo["MacAddress"]));

where the Adapter class is defined as a straightforward two-property encapsulating class and instances are kept in the adapters collection which allows for end-user selection in case of more than one adapter is present in the system.

This code requires a reference to System.Management.dll. For additional WMI class information see Win32_NetworkAdapterConfiguration.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

This has been annoying me since a couple of weeks for now, so I thought to express my frustration online :-). Vista uses the CTRL-SHIFT-F9 key combination to turn on/turn off the Aero experience. Guess how much I'm using this key combination to make a VS2005 project breakpoint free? :P

I was looking for a registry hack to disable this key combination (or to change it) but didn't found anything. Someone a suggestion? And no, I'm not going to assign another key combination in VS2005; I'm an old-fashioned guy that doesn't like to change habits especially when it comes down to shortcuts (did you know ALT-D does still - thanks god - work in IE7 although there is no Address thing somewhere on the screen?; did you know all Office 2003 key combinations for menus still work in 2007 Office System which lacks menus?).

Let's file a bug (or comment) :-).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Today, I'm in the middle of upgrading an existing .NET 1.x application to .NET 2.0 in Visual Studio 2005, running on Vista. Just to set your mind, the application acts as a shell replacement to support a smooth log on to a remote terminal server (or the access the local browser) and can be used in thin client scenarios on Windows 2000 or Windows XP. I'll post some screenshots later on if time permits.

Now to the serious stuff. For a couple of months (since Vista beta 2) now I'm working on Windows Vista on a day-to-day basis. The application writes to the registry in HKEY_LOCAL_MACHINE to store settings (the reason for that is a historical one and has to do with the "shell replacement" character of the application). A piece of code looks as follows:

settings = Registry.LocalMachine.OpenSubKey("SOFTWARE\\BdsSoft\\ThinClient");

and (in case settings appears to be null and the setup wizard pops up the very first time the app is executed)

Registry.LocalMachine.CreateSubKey("SOFTWARE\\BdsSoft\\ThinClient");

So, to inspect what happened in the registry, I opened up regedit.exe (of course causing the Vista's User Account Control dialog to pop up with a nice sound) and navigated to the key in question. However, nothing there :-(.

This is what happened: Windows Vista protects applications from writing to HKLM but leaves the illusion the app can just do whatever it wants (as would it be an administrator on the box). For that purpose, Vista virtualizes the registry (as well as parts of the file system, such as Program Files). In my case, the settings ended up in the so-called VirtualStore than can be found through HKEY_USERS, as shown below.

Have fun!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

This is my first post using Windows Live Writer Beta on Windows Vista.

Setup of my blog was very easy so far; the application knew about Community Server and guided me through the process to set up all the required stuff. My previous experience using Word 2007 was not so good because of the ugly result when pasting code (tried it different ways, still had to do a lot of editing online). So fingers crossed this one does a better job.

Download the tool over here.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Fellow Belgian software guys, check out this great (free of charge) event that will take place in Brussels on September 25. Peter Himschoot and Ingo Rammer will introduce you in the wonderful world of WPF, WCF, WF (together making up the .NET Framework 3.0 formerly known as WinFX).

More information can be found on http://www.microsoft.com/belux/msdn/nl/events/2006/net30.mspx. Don't forget to participate in the session voting too!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Today, the LINQ-SQO ("A custom implementation of the .NET Standard Query Operators from LINQ") project was officially added on CodePlex on the following URL: http://www.codeplex.com/Wiki/View.aspx?ProjectName=LINQSQO. The project's mission statement is below:

This project helps you to understand how the .NET Standard Query Operators work. Those operators are a crucial part of the LINQ technology that was announced by Microsoft at the PDC 05 conference in Los Angeles. For an overview of LINQ, please take a look at http://msdn.microsoft.com/data/ref/linq. The source code included with this project is based on the LINQ May 06 CTP which includes a specification for the .NET Standard Query Operators.

All future work on this project will happen online at CodePlex. If you think you can add value (additional documentation, higher code coverage for testing, additional implementation efforts, etc) to this project, please contact me. See my previous blog post for more information: http://community.bartdesmet.net/blogs/bart/archive/2006/07/04/4115.aspx.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

I've always been somewhat sceptical on the field of "tabbed browsing". I just couldn't understand why people like it so much, as it were the new Mekka of internet browsing. Putting together unrelated things in one single window seems so unnatural to me (how to find it as an ALT-TAB freak, or better WIN-TAB freak nowadays on Vista?). And quite frankly, I couldn't find myself pressing CTRL-T instead of CTRL-N in the previous IE7 betas. Or just a little now and then, ending up with even more mess than before ("oh my, in which IE window did I put that page?"). I'm just an ALT-TAB lover and will always be.

So, this IE7 beta 3 thing just blew me away: "Use most recent order when switching tabs with Ctrl+Tab" under Internet Options, Advanced. Guess what? IE7 now knows what power users like me really want: CTRL-TAB functionality that preserves the "most recent order" at all times, just like the good old ALT-TAB of Windows. I might consider to press CTRL-T more often now. Maybe I'll end up in the tabbed browsing club after all.

More info on the IE team blog on MSDN.

PS: I'm not an "alternative browser" guy, so I don't know whether this "Use most recent order when switching tabs with Ctrl+Tab" does exist in other browsers out there in the wild. But I guess not :p.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

More Posts « Previous page