Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Win8.1 will fire unload and load event to the WPF application when we close and reconnect to this machine using RDC from win7 or other OS

This is a strange issue only in Win8.1.

As we all know, if there is a running application in a machine, there should not be any other behavior against the application when we connect/disconnect/reconnect to this machine by Remote Desktop Connection. However, we found that Win8.1 will fire unload and load events to the WPF application when we close and reconnect to the machine using RDC. And this is an unwanted behavior which may cause error.

Here are the stable reproduce steps:

  1. Write a WPF application which contains a button and handles the unload and load events of this button.
  2. Using RDC to connect to a Win8.1 from Win7 for example.
  3. In the remote desktop, run this WPF app.(a load event will be recorded in a.txt).
  4. Close the RDC by clicking the 'x'.
  5. Connect to this Win8.1 again.
  6. You will see the unload and load events have been fired.

If the WPF app runs in Win7 or Win server 2008, those events will not be fired.

So, I think it is a unwanted behavior in Win8.1. Is that a bug in Win8.1 RDP? Or is that a new feature?

like image 700
capcom923 Avatar asked Jul 03 '14 05:07

capcom923


1 Answers

This occurs because reconnecting RDP notifies the WPF code that session and screen has changed. WPF needs to rebuild its DirectX resources and probably handle an updated screen size (even though resolution may be the same). This makes sense b/c the RDP client can specify different capabilities such as the graphics level and other properties from the RDP "Experience" tab. WPF does not determine that the parameters are all the same as the last time a connection occurred and it triggers a new render and layout cycle (makes sense since colors and screen resolution may have changed). This leads to controls being re-loaded and a new Loaded event firing.

You can see much of the gory details of this by examining HwndTarget.cs in the .NET source. Search this file for "session" and you'll see a LOT of handling for session disconnect/reconnect.

http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndTarget.cs,f20f989ef219e391

If you want to find a way to avoid doing extra work in your Loaded/Unloaded code you may have to move it to a function which you make sure you only call once via a flag or null check.

You can witness what's happening by adding a breakpoint on your Loaded event handler and going to Tools > Options, Debugging and un-check "Enable Just My Code", and check "Enable .NET framework source stepping" and check "Enable Source Server" support. When you connect RDP, the bkpt will trigger and the call stack will show a resize event among other levels of calls. This was probably due to WPF getting a WM_DISPLAYCHANGE as well and having everything re-layout in case there's more or less resolution with this connection.

like image 169
jschroedl Avatar answered Sep 17 '22 23:09

jschroedl