DCSIMG
June 2011 - Posts - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

June 2011 - Posts

WPF/Silverlight Data Binding Tip: FallbackValue

Published at Jun 25 2011, 03:44 PM by pavely

Consider the following piece of XAML (part of an Image Viewer application), that wants to set the Window title (in WPF) based on the currently loaded image file:

Title="{Binding ImagePath, StringFormat=Image Viewer ({0})}"

This assumes that a DataContext exists, and exposes a property named ImagePath. This works well if such an object actually exists. But what happens when the application starts up and there is no image loaded yet, meaning the DataContext remains null? The Title would show nothing, because the binding fails. How can we fix that?
One way would be to create a dummy DataContext with the ImagePath property set to some value we want. But that’s cumbersome and limiting. What if we wanted a completely different title when there is no image?

Fortunately, there is a way. The FallbackValue property of the Binding object (actually BindingBase) allows setting a value if the binding can’t complete. Here’s a way to get something with a null DataContext:

Title="{Binding ImagePath, StringFormat=Image Viewer ({0}), FallbackValue=Image Viewer - Select Open to load a file}"

This shows the fallback value when the binding is unable to provide a value.

GetShellWindow vs. GetDesktopWindow

Published at Jun 18 2011, 09:06 PM by pavely

In his post about running a process as a standard user from an elevated process, Aaron Margosis uses a technique that gets the access token of the shell process (typically explorer.exe) and uses that token to launch the new process (Sasha Goldshtein also blogged about that).

The first thing his code does is try to locate the shell process id. One way is to look for “explorer.exe” in the list of processes, but that’s a bit limiting, as there may be a different shell, or it may have been renamed for whatever reason. His code calls GetShellWindow to get the shell window handle, followed by GetWindowThreadProcessId that returns the window’s creator thread (and optionally its parent process). A similar looking function is GetDesktopWindow, which seems at first glance as a better candidate, or at least an equivalent. Let’s test that:

HWND hShell = ::GetShellWindow();
HWND hDesktop = ::GetDesktopWindow();
cout << "Shell window: " << hShell << endl;
cout << "Desktop window: " << hDesktop << endl;

DWORD idShell, idDesktop;
::GetWindowThreadProcessId(hShell, &idShell);
::GetWindowThreadProcessId(hDesktop, &idDesktop);

TCHAR filename[MAX_PATH];
if(GetImageFileName(idShell, filename, MAX_PATH))
    wcout << "Shell process: " << filename << endl;

if(GetImageFileName(idDesktop, filename, MAX_PATH))
    wcout << "Desktop process: " << filename << endl;

GetImageFileName is a simple helper for getting the process image name:

BOOL GetImageFileName(DWORD pid, TCHAR* name, DWORD size) {
    HANDLE hProces = ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
    if(!hProces) return FALSE;
    DWORD sz = size;
    BOOL success = ::QueryFullProcessImageName(hProces, 0, name, &sz);
    ::CloseHandle(hProces);
    return success;
}

This is the result of running this code:

image

The difference is evident: GetShellWindow returns the “program manager” window created by explorer.exe, while GetDesktopWindow returns the window created by the Windows subsystem process (csrss.exe). This code requires running elevated, so that opening a handle to csrss.exe succeeds, as it runs (naturally) under the all powerful system account.

What’s the relation between these two Windows? We can find out using the Spy++ utility (spyxx.exe from the Visual Studio tools). Run Spy++ (by default elevated). You should see something like this:

image 

If the Windows window is not shown, select Spy->Windows from the menu. Note that the root window handle is the same as the desktop window handle reported by our simple application. This window is owned by csrss.exe. That means it exists whether a shell process exists or not.

Now let’s find the shell window. Select Search->Find Window from the menu and type the handle reported by the application (1013A in this case) (hex is ok).

image

Click OK. The selected window is now this one:

image

This is the “Program Manager” of explorer.exe. How can we verify that? Right click the window and select Properties:

image

Click the Process tab:

image

Now click the shown process id:

image

This is indeed explorer.exe.

If we go back and look at the shell window again, and go up in the tree to its parent, we would find it to be the desktop window itself!

A ‘Proper’ WeakReference Class

Published at Jun 04 2011, 12:12 PM by pavely

The WeakReference class that exists since .NET 1.0 can be used to wrap an object while not being the one keeping it alive. This may be useful in an “Observer” pattern scenario, where a client registers for some notification, but “forgets” to unregister. That means that with a normal reference, even if the client is no longer needed, it keeps getting notifications because the server object keeps a strong reference to the client.

Here’s a simple example:

  1. class BasicSubject {
  2.     List<INotify> _clients = new List<INotify>();
  3.  
  4.     public void Attach(INotify client) {
  5.         _clients.Add(client);
  6.     }
  7.  
  8.     public void DoSomething() {
  9.         // notify clients
  10.         foreach(var client in _clients)
  11.             client.Update();
  12.     }
  13.  
  14.     public void Detach(INotify client) {
  15.         _clients.Remove(client);
  16.     }
  17. }
 

A simple client (observer) may be implemented like so:

  1. class MyObserver : INotify {
  2.     public void Update() {
  3.         Console.WriteLine("Update received!");
  4.     }
  5. }

Now, we can test:

  1. static void TestBasicSubject() {
  2.         var subject = new BasicSubject();
  3.         var observer = new MyObserver();
  4.         subject.Attach(observer);
  5.  
  6.         subject.DoSomething();
  7.  
  8.         // not interested anymore
  9.         observer = null;
  10.         subject.DoSomething();    // still notified
  11.  
  12.         GC.Collect();
  13.         subject.DoSomething();    // still notified yet!
  14.     }

How many times would the observer be notified? Three times. The call in line (12) to GC.Collect is not enough, because the client is not garbage – the subject holds a strong reference to the client.

The solution is obvious – just call Detach on the subject and you’re good. The problem is that sometimes clients forget to detach, and sometimes it’s difficult to call it in the right moment – if the client is used from different threads, for instance, Detach needs to be called at the right time, i.e. not too soon.

The subject can be more defensive – not hold on to the observer too tightly using the WeakReference class. Here’s a revised subject:

  1. class BetterSubject {
  2.     List<WeakReference> _observers = new List<WeakReference>();
  3.  
  4.     public void Attach(INotify notify) {
  5.         _observers.Add(new WeakReference(notify));
  6.     }
  7.  
  8.     public void Detach(INotify notify) {
  9.         foreach(var wr in _observers)
  10.             if(wr.Target == notify) {
  11.                 _observers.Remove(wr);
  12.                 break;
  13.             }
  14.     }
  15.  
  16.     public void DoSomething() {
  17.         for(int i = 0; i < _observers.Count; i++) {
  18.             var notify = (INotify)_observers[i].Target;
  19.             if(notify == null) {    // garbage collected
  20.                 _observers.RemoveAt(i);
  21.                 i--;
  22.             }
  23.             else
  24.                 notify.Update();
  25.         }
  26.     }
  27. }

Every observer is wrapped in a WeakReference. The Target property points to the real object, or null, if it has since been garbage collected. Let’s test it:

  1. static void TestBetterSubject() {
  2.     BetterSubject subject = new BetterSubject();
  3.     MyObserver observer = new MyObserver();
  4.     subject.Attach(observer);
  5.  
  6.     subject.DoSomething();
  7.  
  8.     observer = null;
  9.     subject.DoSomething();    // notify
  10.     GC.Collect();
  11.  
  12.     subject.DoSomething();    // not notified!
  13. }

Now we only get two notifications! That’s because the subject is holding a weak reference to the observer, so cannot be the one keeping it alive if no other string references exist.

The WeakReference class has two “issues”:

1. It does not implement IDisposable, so the underlying GCHandle is freed only when it is garbage collected.

2. It’s not generic (somewhat understandable, as it exists since .NET 1.0)

We can fix both these issues by either deriving from WeakReference (it’s prepared for that, most of its members are virtual), or create our own implementation.

I decided to go for the latter, as the WeakReference is not immutable (it’s target can be replaced) and I like immutability these days. We can also simplify it a bit. Here one way to go about it:

  1. public sealed class WeakReference<T> : IDisposable where T : class {
  2.     GCHandle _handle;
  3.  
  4.     public WeakReference(T obj) {
  5.         _handle = GCHandle.Alloc(obj, GCHandleType.Weak);
  6.     }
  7.  
  8.     public T Target {
  9.         get { return _handle.IsAllocated ? _handle.Target as T : null; }
  10.     }
  11.  
  12.     public bool IsAlive {
  13.         get { return _handle.Target != null; }
  14.     }
  15.  
  16.     public void Dispose() {
  17.         _handle.Free();
  18.         GC.SuppressFinalize(this);
  19.     }
  20.  
  21.     ~WeakReference() {
  22.         _handle.Free();
  23.     }
  24.  
  25.     public static bool operator ==(WeakReference<T> a, WeakReference<T> b) {
  26.         return a.Equals(b);
  27.     }
  28.  
  29.     public static bool operator !=(WeakReference<T> a, WeakReference<T> b) {
  30.         return !(a == b);
  31.     }
  32.  
  33.     public override bool Equals(object obj) {
  34.         return _handle.Equals(((WeakReference<T>)obj)._handle);
  35.     }
  36.  
  37.     public override int GetHashCode() {
  38.         return _handle.GetHashCode();
  39.     }
  40. }

Now its usage is a bit more intuitive:

  1. class Subject {
  2.     List<WeakReference<INotify>> _observers = new List<WeakReference<INotify>>();
  3.  
  4.     public void Attach(INotify observer) {
  5.         _observers.Add(new WeakReference<INotify>(observer));
  6.     }
  7.  
  8.     public void DoSomething() {
  9.         for(int i = 0; i < _observers.Count; ++i) {
  10.             INotify notify = _observers[i].Target;
  11.             if(notify != null)
  12.                 notify.Update();
  13.             else {
  14.                 _observers[i].Dispose();
  15.                 _observers.RemoveAt(i);
  16.                 --i;
  17.             }
  18.         }
  19.     }
  20.  
  21.     public void Detach(INotify client) {
  22.         foreach(var observer in _observers) {
  23.             if(observer.Target == client) {
  24.                 observer.Dispose();
  25.                 _observers.Remove(observer);
  26.                 break;
  27.             }
  28.         }
  29.     }
  30. }

My WeakReference<T> is not serializable (the original WeakReference is), but that’s not  too difficult to add.