Silverlight Shinobi

Secret techniques, tips and deadly tricks with Silverlight!

Silverlight Shinobi

  • Windows 8: Windows Store App Labs!

    Windows Store App Labs!

    Windows Store App Labs (WSALs) are here! A place where you can access Windows 8 devices, get design help, and meet with Windows 8 Experts to make your app great! All for free!

    Get technical guidance from Windows 8 Experts
    Our Windows Store app developer experts are on-hand to help you get started, to test your app and offer any technical advice you need!
    We can help you with coding tips, debugging, and prepping your app to submit to the Windows Store. 

    Check out and test on the newest Windows 8 devices
    Test your app on a variety of screen sizes, input methods, and chipsets with the latest Windows 8 devices including Windows RT tablets, Ultrabooks, All-in-Ones, and more.
    Designers will review your app mock-ups or your complete app and provide feedback on how you can improve your app’s layout, navigation, live tile, and other UI elements.

    As you get started - check out 5 tips to help you get your app certified quickly, top 10 app secrets of success, Win8 Forms and more helpful information on our lab resources page.

    All for free!

    Space is limited.  Please register for a lab in your location:

     

    Country

    City

    Link

    Canada

    Vancouver

    https://applabs.msregistration.com/LabList.aspx?drop=52&userid=null#list

    US

    San Francisco/Santa Clara

    https://applabs.msregistration.com/LabList.aspx?drop=139&userid=null#list

    Canada

    Toronto

    https://applabs.msregistration.com/LabList.aspx?drop=40&userid=null#list

    US

    New York

    https://applabs.msregistration.com/LabList.aspx?drop=140&userid=null#list

    England

    London

    https://applabs.msregistration.com/LabList.aspx?drop=9&userid=null#list

    France

    Paris

    https://applabs.msregistration.com/LabList.aspx?drop=13&userid=null#list

    Belgium

    Brussels

    https://applabs.msregistration.com/LabList.aspx?drop=25&userid=null#list

    Czech Republic

    Prague

    https://applabs.msregistration.com/LabList.aspx?drop=25&userid=null#list
     

    Sweden

    Kista

    https://applabs.msregistration.com/LabList.aspx?drop=22&userid=null#list
     

    Turkey

    Istanbul

    https://applabs.msregistration.com/LabList.aspx?drop=22&userid=null#list

    India

    Mumbai

    https://applabs.msregistration.com/LabList.aspx?drop=22&userid=null#list

    India

    Bangalore

    https://applabs.msregistration.com/LabList.aspx?drop=3&userid=null#list

    China

    Beijing

    https://applabs.msregistration.com/LabList.aspx?drop=11&userid=null#list

    China

    Shanghai

    https://applabs.msregistration.com/LabList.aspx?drop=58&userid=null#list

     

     

     

  • HTML5 in MVC

    Live Demo - Source Code


    HTML5 is a hot topic lately and developers are eagerly investigating ways to use HTML5. One of the more widely discussed capabilities are the built-in form type controls enforcing validation and allowing for placeholder values - new input types such as “color”, “date|datetime”, “email”, “phonenumber” are now supported in browsers such as Opera and Firefox.

    Example:

    <input name="EmailAddress" placeholder="ex
    youremail@here.com" required="true" type="email" />


    HTML5 is not yet standardized and not supported in the more broadly utilized browsers … so how can we leverage these capabilities when supported … and yet provide a similar experience for users of non-html5 browsers?

    It was this problem that motivated me to create the example project I’ll be covering today – and I threw in a few other useful examples to scenarios often requested by customers.

    First I leveraged the nuget package mvchtml5templates which provides new EditorTemplates for the HTML5 types. If you haven’t discovered nuget yet – you are in for a treat. Install the latest version from nuget.org – and you can set Package Manager to check for updates automatically via VS2010 Tools|Options|Package Manager| Automatically "Check for Updates" checkbox.

    The EditorTemplates will output <input> with the native html5 types, then I used Modernizer in Javascript to check if the type is supported by the browser.

    Example:

    if (!Modernizr.inputtypes.email))…

    Modernizer uses a combination of pre-defined browser capabilities and real-time client-side capability checks to determine this. If it is supported – then we get the benefit validation and native browser controls for the types. If not – then we leverage JQuery for validation, generating controls for the given type (eg date and color) and placeholder.

    There are also a few of other scenarios I’ve covered in this example that I’ll describe in future blog posts such as:

    • Using a JQuery Dialog for the item editing with Ajax and the AntiForgeryToken.
    • Deleting a row from the grid using Ajax and without a full grid refresh.
    • Leveraging ViewModels.
    • Supporting IoC / Repository pattern.
    • Dev vs. Production setup for Jquery references
    • T4MVC

     

  • Silverlight pre-cache dlls in browser cache - the secret compressed dlls as png Trick!

    This is a trick used by the Bing Maps Silverlight folks - but as far as I can tell (by Binging the web) I"m the first to actually blog about this secret technique and show you how it's done.

    I'm using the browser’s cache to download our dlls as PNG files from the ASPX page hosting the Silverlight control, then dynamically load those dlls after the application loading and they are already be in the browser’s cache.

    To keep this blog relatively short and sweet - I'll point out only the key parts of the example solution under each project - the rest of the code is self-explanatory.

    The solution contains 3 projects: (1) MyExternalLib (2) PngPerformanceTrick (3) PngPerformanceTrick.Web

    MyExternalLib
    This contains a page (representing your view) and a simple class library. This is a Silverlight Application project that when compiled creates a separate xap, the xap (as normal) is in fact a compressed zip file containing the application manifest (AppManifest.xaml) and the dll (MyExternalLib.dll). This library is NOT included in the main project's xap (PngPerformanceTrick) - thus reducing the over-all initial download time.Yet - we are able to have strong type references to this library from our main application project. This is a common technique used normally by adding a reference to the project and then setting the property on the reference to "Copy Local", and adding the attribute "MethodImplOptions.NoInlining" to avoid JIT issues prior to lazy-loading.

    I also added a post-build event to this project which copies the output xap to the web project's ExternalLibs folder as a png file. This could be done manually... but this approach makes it much faster to develop code and debug without any manual steps in-between.

    Post-Build Event (found by right-clicking project, properties, Build Events)

    Copy $(TargetDir)$(TargetName).xap $(SolutionDir)PngPerformanceTrick.Web\ExternalLibs\$(TargetName).png


     

    PngPerformanceTrick
    This is the main entry point application. It has the ExternalLibLoader and a single MainPage. The mainpage uses the ExternalLibLoader to load our library - and display's the ExamplePage on the mainpage. This project contains the ExternalLibLoader which loads the external library as a png (by name). As the web project already loaded this as a png - it will reside in the browser's cache improving loading performance. You can open up the xap for this project (by renaming to zip) and verify the dlls inside only - and it only contains the dll for this project (PngPerformanceTrick.dll).

    To accomplish this when I added the MyExternalLib project as a reference I right-clicked the reference, Properties, Copy Local=false. Also you will note that in the MainPage.cs where I actually use the MyExternalLib I set

    [MethodImpl(MethodImplOptions.NoOptimization|MethodImplOptions.NoInlining)]

    That is to avoid the JIT from pre-compiling prior to actually dynically loading the external library. That is handled in the ExternalLibrLoader.
     

    PngPerformanceTrick.Web
    This is the simple web project that hosts the main application xap. The only "fancy" thing here is that in the aspx page I've got an image tag that references the external library as a png. I've got some aspx code in there to iterate through all files in the "ExternalLibs" folder and create an image tag for each - so that as devs add more external projects this doesn't have to be updated.

    Tip: (You could speed things up even further by putting the PNGs in separate domains to get around the browser’s port limit for downloads).

    And that's it - now you can really maximize your silverlight application performance.

    If you have any questions or problems using the sample code, or suggestions for improvements - please let me know.

     

     

     

     

     

     

  • Identifying the root of a memory leak in Silverlight using windbg

    Considering all of the nasty blog comments out there you would think it be easy to create a test project to reproduce a leak – it wasn’t. I downloaded the latest version of SL4 and first attempted to create a leak using the inline template, then control template, then listbox items – all of these prior issues now appear to be resolved as I could not reproduce a leak using any of them with Build 4.0.60310.0 (Released April 19, 2011). In reviewing the release history (which I should have done prior to attempting to reproduce these myself) I can see various leaks were already fixed: nested popup (Build 4.0.60310.0), Controls leak INotifyDataErrorInfo.ErrorsChanged, Datagrid leak (4.0.60310.0), Inline data template leak (4.0.60129.0), Mousecapture & usercontrol and various leaks (4.0.50826.0).  

    So I ended up creating a more mundane simple leak that may occur if you register an event-handler somewhere such as in your view to an object that remains alive (such as a shared model) - and never unregister your event-handler and keep the event publisher instance alive. If you have something more exciting in a simple demo project please email me.  First I’ll show you this with windbg (free) and then I’ll show you in ANTS (my new favorite but not free debugging tool). In either case regardless of the tool it helps to have an idea where the leak(s) may be in advance. In other words – the tools don’t know the software’s intention. If you intend to have something collected then you can use these techniques to test to see if they are indeed collected or not. You can also check the number of instances and size of objects and inspect those in Gen 2 and LOH as prime suspects but this walkthrough doesn’t focus on that technique – just touches on it.

    Step 1

      1. Download the leaky sample zip file, unzip and open the VS 2010 project, set web project as startup and F5 debug to build and run it once. Copy the localhost url (including port) to notepad, and stop debugging in VS – we will be using windbg for this exercise.  

    1. Open that url directly in IE (you may want to close other instances of IE except for these instructions).
      1. Example: http://localhost:21589/LeakyExamplesSLTestPage.aspx#/Home

     

    1. Click “eventpinned”, then click back to home, then click “Force a GC”.

    Step 2

    1. If you haven’t already, install ProcessExplorer (free from Microsoft’s sysinternals). Use the target symbol from the toolbar – drag it onto your executing SL app to find and note the correct process ID. Also check that process “Image Type” column in ProcessExplorer to determine if it is 32 or 64 bit. If you don’t see that column in ProcessExplorer – right-click the column header and add it.

    Step 3

    1. Open the version of debugdiag that corresponds to your process Image Type (eg DebugDiag (x86) for 32bit). (Run à debugdiag).
    2. Find your process by ID, right-click, “create full user dump”

    Step 4 (enter windbg

    1. Open the corresponding version of Microsoft’s windbg (x86 for debugging your 32bit process) – right-click “Run as Administrator”. If you haven’t downloaded – go to windbg download – if you scroll to the bottom you will find direct links to both versions.
    2. Open the dump file you just created (File | Open Crash Dump)
    3. Now let’s load the Silverlight debugging extensions (sos) and the silverlight coreclr.

    0:000> .load C:\Program Files (x86)\Microsoft Silverlight\4.0.60531.0\mscordaccore.dll
    0:000> .load C:\Program Files (x86)\Microsoft Silverlight\4.0.60531.0\sos.dll

        4. Now let’s check the managed threads (remember though from previous session that your Silverlight thread may not show up in managed threads.. you may need to execute ~*kL):

     0:000> !threads
    ThreadCount: 3
    UnstartedThread: 0
    BackgroundThread: 3
    PendingThread: 0
    DeadThread: 0
    Hosted Runtime: yes
    PreEmptive GC Alloc Lock
    ID OSID ThreadOBJ State GC Context Domain Count APT Exception
    4 1 4d90 08b47888 220 Enabled 0a858950:0a859fe8 08a10978 0 STA
    29 2 578c 08a4f028 b220 Enabled 00000000:00000000 08a10978 0 MTA (Finalizer)
    30 3 21c0 08a52ab0 1220 Enabled 00000000:00000000 08a10978 0 Ukn

     

    1. Okay – that confirms we’ve got sos loaded…. but since we are not at a breakpoint of anything interesting in the code we aren’t searching for the clrstack… so we don’t need to track down the thread at this time. Instead we care about what is held in memory. Let’s get a summary of what’s in the heap:

     0:000> !eeheap -gc
     Number of GC Heaps: 1
     generation 0 starts at 0x0a661018
     generation 1 starts at 0x0a66100c
     generation 2 starts at 0x0a661000
     ephemeral segment allocation context: none
     segment begin allocated size
     0a660000 0a661000 0a859ff4 0x1f8ff4(2068468)
     Large object heap starts at 0x0b661000
     segment begin allocated size
     0b660000 0b661000 0b668260 0x7260(29280)
     Total Size: Size: 0x200254 (2097748) bytes.
     ------------------------------
     GC Heap Size: Size: 0x200254 (2097748) bytes.
     

    1. Interesting – but not what we are looking for. If you had serious memory leak problems you would see here Gen2 and the LOH grow between two memory dump snapshots. Now let’s look at all the objects in the heap… remember we are checking to see if our view (EventPinnedPage) has been GC’ed or not…

    0:000> !dumpheap –stat
    Statistics:
    MT Count TotalSize Class Name
    7aa1a178 1 12 System.Windows.Hosting.ManagedRuntimeHost
    7aa1941c 1 12 System.Windows.Browser.ManagedObjectInfo+ScriptMemberGroup
    [ ---- RESULTS CUT OUT FOR BREVITY --- ]
    794aff90 135 250928 System.Byte[]
    794b1a50 8284 274040 System.Object[]
    794c05e8 7939 365732 System.String
    Total 45639 objects

    1. Well…. There’s a lot of instances in the heap. Typically the System.String are expected and not something to worry about – but I can’t find my “EventPinnedPage” in this huge list. Let’s try a shell search for it:

    0:000> .shell -ci "!dumpheap -stat" find "Pinned"
    084b2164 2 208 LeakyExamplesSL.Views.EventPinnedPage
    .shell: Process exited

     Bingo we found it and it’s still in memory – let’s take a look at it:
    0:000> !dumpmt -md 084b2164
    EEClass: 070c5c0c
    Module: 06dc49e0
    Name: LeakyExamplesSL.Views.EventPinnedPage
    mdToken: 02000007
    File: LeakyExamplesSL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
    BaseSize: 0x68
    ComponentSize: 0x0
    Slots in VTable: 67
    Number of IFaces in IFaceMap: 4
    --------------------------------------
    MethodDesc Table
    Entry MethodDesc JIT Name
    792ca980 790ca0e4 PreJIT System.Object.ToString()
    792ca9a0 790ca0ec PreJIT System.Object.Equals(System.Object)
    792caa10 790ca10c PreJIT System.Object.GetHashCode()
    792caa20 790ca124 PreJIT System.Object.Finalize()
    082c65a0 084b2118 JIT LeakyExamplesSL.Views.EventPinnedPage..ctor()
    082c6780 084b210c JIT LeakyExamplesSL.Views.EventPinnedPage.InitializeComponent()
    [-- deleted for brevity --- ]
    06dcca75 084b2120 NONE
    LeakyExamplesSL.Views.EventPinnedPage.commander_SomethingChanged(System.Object, System.EventArgs)
    082c6ca0 084b212c JIT LeakyExamplesSL.Views.EventPinnedPage.EventPinnedPage_Unloaded(System.Object, System.Windows.RoutedEventArgs)
     

    1. Okay but to find out what is causing our instance(s) of this to get stuck in memory we need to get to the instances themselves first. This command will list all instances in memory of a type (and their size) and most importantly – their virtual address.
    0:000> !dumpheap -type LeakyExamplesSL.Views.EventPinnedPage
    Address MT Size
    0a78b844 084b2164 104
    0a7ffc30 084b2164 104
    total 0 objects
    Statistics:
    MT Count TotalSize Class Name
    084b2164 2 208 LeakyExamplesSL.Views.EventPinnedPage

    Now lets take a look at one of those instances and find out what is causing it to stay around like that one pesky party guest that hangs out when he’s no longer welcome…

     

    0:000> !gcroot 0a78b844
    Note: Roots found on stacks may be false positives. Run "!help gcroot" for
    more info.
    Scan Thread 4 OSTHread 4d90
    Scan Thread 29 OSTHread 578c
    Scan Thread 30 OSTHread 21c0
    DOMAIN(08A54278):HANDLE(Pinned):6e112f8:Root: 0b664260(System.Object[])->
    0a78b8ac(LeakyExamplesSL.Common.MockCommandManager)->
    0a801b40(System.EventHandler)->
    0a801b28(System.Object[])->
    0a78d954(System.EventHandler)->
    0a78b844(LeakyExamplesSL.Views.EventPinnedPage)

    Well – that’s a pretty clear picture that the event handler to MockCommandManager is causing the problem. I must say that at this point Red Gates ANT memory profiler does a wonderful diagram (copied below). After playing around with that tool for a while I may just shell out the $500 out of pocket to use it.

     

     

  • Debugging Silverlight with windbg (finding eaten exceptions)

    Lately lot's of people are asking me the question “Isn’t Silverlight dead?” Even with the post rumors still abound strong – likely due to the prevalence of html5 in the windows 8 demo. Today two people asked me. I tell them what I tell you – stay tuned to the 2011 Build Conference September 13th

    Today we will start where we left off in last post and we will take a quick look at exceptions... so load up windbg just like you did last week.

    Note that the “4” represents the 4th thread. We switched to that thread in the last post. Here we are listing all objects of type “Exception” that exist on the heap.

    0:004> !dumpheap -stat -type Exception

    And that gives us the results below.

    total 0 objects

    Statistics:

    MT            Count    TotalSize Class Name
    0cacdb20        1           32 MS.Internal.Error+GetExceptionTextDelegate
    0caa8a08        1           32 MS.Internal.Error+ClearExceptionDelegate
    0ca9f974        1           32 System.EventHandler`1[[System.Windows.ApplicationUnhandledExceptionEventArgs, System.Windows]]
    0c403200        1           32 System.UnhandledExceptionEventHandler
    0c42d5ec        1           80 System.UnauthorizedAccessException
    0c42b4ec        1           80 System.ExecutionEngineException
    0c42b45c        1           80 System.StackOverflowException
    0c42b414        1           80 System.OutOfMemoryException
    0c422a48        1           80 System.Exception
    0c421990        1           88 System.ArgumentOutOfRangeException
    0c4285fc        1           92 System.IO.FileNotFoundException
    792c044c        2          160 System.UriFormatException
    0c42d8dc        2          160 System.Threading.ThreadAbortException

    Total 15 objects

    _____________________________________________________________________

    Now you may recall we only threw (and caught) 3 types of Exceptions (ArgumentOutOfRangeException, FileNotFoundException, UnauthorizedAccessException) and we can see those there… but there are tons more also - so you may wonder where all of these exceptions on the heap are coming from? Some exception info is pre-loaded in the heap for certain exception types [todo: add more info here].

     Now let’s take a look at the “UnauthorizedAccessException”

     0:004> !dumpheap -mt 0c42d5ec       

    Address       MT     Size
    09e7a798 0c42d5ec       80    
    total 0 objects
    Statistics:

    MT    Count    TotalSize Class Name
    0c42d5ec        1           80 System.UnauthorizedAccessException

    Total 1 objects
    ____________________________________________________

    So if there are multiple instances of the same type of exception they will all be listed there and you can look at them individually. In this case there is only one, so let’s do a Print Exception (pe) on that address. 

    0:004> !pe 09e7a798

    Exception object: 09e7a798
    Exception type:   System.UnauthorizedAccessException
    Message:          you are unauthorized to do that!
    InnerException:   <none>
    StackTrace (generated):

        SP       IP       Function
        0342D6BC 00601F25 UNKNOWN!SLHelloWndbg.MainPage.button1_Click(System.Object, System.Windows.RoutedEventArgs)+0xd5

    StackTraceString: <none>
    HResult: 80070005

    And that gives us the exception details and the custom message string that we are throwing in the application. So keep in mind – even though this exception was eaten (caught and handled) we can still determine what exceptions are being thrown. These have a relatively short life-span on the heap so be sure to capture your dump at the right time.

    In DebugDiag (comes with Windows SDK) cancel out of the wizard. Then go to “Tools” in the toolbar, click “Add Rule” and add a first chance exception configuration (by clicking “Exceptions” in the Advanced Settings). Play around with these settings – you may want to make your action limit greater (say 50) to take the memory dump with several hidden exceptions in the heap for you to then examine. Be sure to point it at the right process (see previous post for details).

       and  

    Ah Grasshopper – you are truly learning very quickly now!

     

  • Grasshopper Level 1 - Debugging Silverlight with windbg startup

    Goal:
    The goal of this walkthrough is to find the stacktrace for a currently executing Silverlight Application and examine it in windbg. This intro will give you the information you need to "break the ice" with using windbg tool for debugging in Silverlight. Building upon these skills you will soon be able to identify memory leaks, find hidden bugs and thread contention in your Silverlight applications ... and snatch the pebble from my hand.

    Let's start off with the simple task of finding the call-stack on an executing Silverlight application. To facilitate this I created a simple Silverlight 4 application that on a button-click it throws (and catches) three types of Exceptions (ArgumentOutOfRangeException, FileNotFoundException, UnauthorizedAccessException) and then prompts with a MessageBox. We are going to focus on the call stack in this blog - but next we will look at the exception details.

    The MessageBox prompt is to pause the application so we can take a memory dump to analyze the call stack at that particular point of interest. It is always important to capture your memory dump at the point you are interested in - processes get spawned, threads get recycled... Later we will look at ways you can configure debugdiag to take a dump when it encounters exceptions (first or second chance) of a particular type for effective debugging of customer issues - but for now this is a great way to get familiar with the initial setup and process for working with windbg and Silverlight.

    Step 1 - Startup / Install Prerequisites
    First go ahead and download the windbg and debugdiag tools.

    You can install the Windows SDK which contains both tools, or individually install the 32 and 64 bit versions. Chances are you will need the 32 bit version - but better to have both for future use.

    Then download and unzip Microsoft's Process Explorer from sysinternals. We will need that to positively identify the correct process.

    Got all that? Ok... let's get started!

    Let's get a simple silverlight application paused somewhere that we can then investigate the call stack and verify some data in the heap. To facilitate this exercise i created a simple project that has one button and throws 3 types of exceptions (). You can download it here, and run it and click the "Go!" button.... or create or use your own application - just be sure to have some dialog open (eg MessageBox) or active process when you take your memory dump.

    Now you need to identify the right process for your executing Silverlight Application. You might think that's a simple matter with Task Manager and you may open it up and add the "Command Line" column to try to identify your Silverlight application - but you are going down the wrong path - you will instead want to use Process Explorer - but let's meander a bit for sake of clarity. If you open Task Manager you will see:

    This isn't much help - other than telling us IE is running in 32bit mode. The command Line parameter won't tell you which process is executing your Silverlight Application - and for those curious the "SCODEF" parameter refers to the parent IE process for the given frame. Pre-frame based IE this approach would've given you the information you need... but not now. Time for the big guns - Process Explorer.

    See the bullseye icon in the Process Explorer toolbar? Click that bullseye and keep your mouse button held down while you drag it directly onto the MessageBox Dialog UI (mine says "Pause here while we look at things...") in your Silverlight UI. You can setup your process explorer and your SL (Silverlight) browser window side-by-side to make this task easier.  Be sure to release it on the dialog UX box or you will get a different process and not the one we want to look at right now.

      

     and that gives us...

    Take note of your PID (Process ID) (mine is #11156).

    Step 2 - Memory Dump
    So first off - is it IE running in 32-bit or 64-bit? That matters because when you take a memory dump you want to do so with a tool running the same way. You can check this in Process Explorer by checking the "Image Type" column. If you don't see that column, right-click the column header and "Select Columns". In this case IE is running 32 bit. Why is this important? You need to take the dump from a tool executing in the same mode - (preferably DebugDiag). For example those clever folks that noticed from Process Explorer you have a right-click "Create Dump" option might have sought to skip the next step... only to discover problems down the line from generating that dump from the 64 bit Process Explorer.

    So - let's open DebugDiag (x86) that comes with Windows SDK (Start|Run - type "DebugDiag").  Cancel out of the wizard, and order the processes under the process tab by PID to locate your process. If you can't locate it, and you've tried F5 to refresh but still can't find it - close DebugDiag and re-open it. I noticed an issue in refreshing processes a few times and that trick seemed to work. See your PID # now? Great.

    Right-click and "Create Full User Dump" and note the location of the file created... now things get fun...

    Step 3 - welcome to the wonderful world of windbg!
    So now let's open up windbg (x86) version same as our memory dump and open the memory dump file. The first thing you will want to do is load the SOS.dll for silverlight (no .NET SOS and psscor will not work for SL).

    In my case that's Silverlight 4:

    > .load C:\Program Files (x86)\Microsoft Silverlight\4.0.60531.0\sos.dll

    you can then do a >.chain to verify what is loaded... and a >.help to see the list of available commands.

    Let's also be sure our symbols are loaded properly so we can get detailed information (create a local folder to store them). For more info on loading symbols see here.

    >.sympath SRV*c:\localsymbols*http://msdl.microsoft.com/download/symbols

    What we really want to get at is the call stack for the currently executing code - but first we have to find the right thread for that and switch context to that thread.

    Try :

    > !threads

    If you get and error like this: Failed to load data access DLL, 0x80004005 then try >.symfix and then try again.

    You should see something like :

    0:000> !threads
    ThreadCount: 3
    UnstartedThread: 0
    BackgroundThread: 3
    PendingThread: 0
    DeadThread: 0
    Hosted Runtime: yes
    PreEmptive GC Alloc Lock
    ID OSID ThreadOBJ State GC Context Domain Count APT Exception
    4 1 2360 08492ef0 220 Enabled 09e7a858:09e7bfe8 08497580 0 STA
    26 2 12b8 084942e8 b220 Enabled 00000000:00000000 08380ca0 0 MTA (Finalizer)
    27 3 20d4 08496c20 1220 Enabled 00000000:00000000 08380ca0 0 Ukn

    Normally this would list the managed thread we are looking for that contains our code... however in this case the SL is executing in coreCLR and not identified as a managed thread. If you were to take the time to switch context on each of these threads and attempt a >!clrstack you may get a mysterious error like this (below) leaving you a little confused...

    0:002> !clrstack
    OS Thread Id: 0x1f14 (2)
    Unable to walk the managed stack. The current thread is likely not a
    managed thread. You can run !threads to get a list of managed threads in the process

    Don't panic. That's why we have to go a little further and execute this command for a full list of the threads:

    >~*kL

    Ok - now you should see a bunch of information scroll by with details for every thread. Take a look through them starting from the top. In my case the first three threads were not familiar - but Thread #4 was the one I am looking for and it was easy to identify by the characteristsics:

     4 Id: 2b94.2360 Suspend: 0 Teb: 7efa9000 Unfrozen
    ChildEBP RetAddr
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0342d538 75240751 user32!PeekMessageW+0x17b
    0342d564 7b22cfea user32!PeekMessageW+0x197
    0342d5ac 7b22cf42 npctrl!RequestFullTrustAppInstall+0x15dc4
    0342d5c8 7b22ce94 npctrl!RequestFullTrustAppInstall+0x15d1c
    0342d5ec 7b799a4e npctrl!RequestFullTrustAppInstall+0x15c6e
    0342d610 0c9a1a0b agcore!MessageBox_ShowCore+0x42
    0342d674 0c9a1aa1 System_Windows_ni!DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, System.String, System.String, UInt32, Int32 ByRef)+0x8b
    0342d698 0ca58e49 System_Windows_ni!MS.Internal.XcpImports.MessageBox_ShowCore(System.String, System.String, UInt32)+0x51
    0342d6a8 0ca58dff System_Windows_ni!System.Windows.MessageBox.ShowCore(System.String, System.String, System.Windows.MessageBoxButton)+0x39
    0342d6f0 00601f3e System_Windows_ni!System.Windows.MessageBox.Show(System.String)+0x1f
    *** WARNING: Unable to verify checksum for SLHelloWndbg.dll
    *** ERROR: Module load completed but symbols could not be loaded for SLHelloWndbg.dll


    However notice the error in the Thread #4 - that helpful error indicates it could not load the symbols for my SL Application... that's because I forgot to point it to my PDBs. That's easy to fix by adding the folder that contains your Silverlight PDBs to the sympath (as shown below). If you don't have the PDBs you may consider reverse-engineering them by finding the XAP file, renaming to ".zip" - opening that archive that contains all the DLLs and then using a program such as the latest version of RedHat's Reflector (or Mono Cecil) to create the project in Visual Studio and then compile in debug mode to generate your PDBs.... or just have the customer send them to you from their Debug folder.

    >.sympath+ C:\files\Visual Studio 2010\SLHelloWndbg\SLHelloWndbg\Bin\Debug
    >.symfix

    And let's check again:

    >~*kL

     (results omitted for brevity sake... but there's no more error). Much better.

    Now since we've found the right thread and gotten our symbols loaded - let's switch our context to that thread and then we can finally do a !clrstack to get the juicy information in the callstack we are seeking:

    0:000> ~4s
    eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000102 edi=0342d588
    eip=75240735 esp=0342d510 ebp=0342d538 iopl=0 nv up ei pl zr na pe nc
    cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
    user32!PeekMessageW+0x17b:
    75240735 83c404 add esp,4
    0:004> !clrstack
    OS Thread Id: 0x2360 (4)
    Child SP IP Call Site
    0342d630 75240735 [InlinedCallFrame: 0342d630]
    0342d62c 0c9a1a0b DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, System.String, System.String, UInt32, Int32 ByRef)
    0342d630 0c9a1aa1 [InlinedCallFrame: 0342d630] MS.Internal.XcpImports.MessageBox_ShowCoreNative(IntPtr, System.String, System.String, UInt32, Int32 ByRef)
    0342d688 0c9a1aa1 MS.Internal.XcpImports.MessageBox_ShowCore(System.String, System.String, UInt32) [f:\dd\xcp\clr\clrlib\pinvokes.cs @ 5733]
    0342d6a4 0ca58e49 System.Windows.MessageBox.ShowCore(System.String, System.String, System.Windows.MessageBoxButton) [f:\dd\xcp\clr\clrlib\System\Windows\MessageBox.cs @ 57]
    0342d6b4 0ca58dff System.Windows.MessageBox.Show(System.String) [f:\dd\xcp\clr\clrlib\System\Windows\MessageBox.cs @ 29]
    0342d6bc 00601f3e SLHelloWndbg.MainPage.button1_Click(System.Object, System.Windows.RoutedEventArgs)
    0342d6fc 0c9f4901 System.Windows.Controls.Primitives.ButtonBase.OnClick() [f:\dd\xcp\clr\clrlib\System\Windows\Controls\Primitives\ButtonBase.cs @ 400]
    0342d710 0ca4f524 System.Windows.Controls.Button.OnClick() [f:\dd\xcp\clr\clrlib\System\Windows\Controls\Button.cs @ 102]
    0342d71c 0c9f4bfe System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs) [f:\dd\xcp\clr\clrlib\System\Windows\Controls\Primitives\ButtonBase.cs @ 818]
    0342d72c 0c9b6341 System.Windows.Controls.Control.OnMouseLeftButtonUp(System.Windows.Controls.Control, System.EventArgs) [f:\dd\xcp\clr\clrlib\control.cs @ 574]
    0342d73c 0c9b5b44 MS.Internal.JoltHelper.FireEvent(IntPtr, IntPtr, Int32, Int32, System.String) [f:\dd\xcp\clr\clrlib\clrlib.cs @ 323]
    0342d780 0ca3cbcf DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int32, Int32, Int32, Int32, IntPtr)
    0342d85c 0668e2dc [ContextTransitionFrame: 0342d85c]

    -------------------------------------------------------------------------------------------

    Very well done Sempai - you are learning quickly! 

    That's enough lessions for today. Later we will look at finding those Exceptions and Memory Leaks.

    Practice!

     

  • ClickOnce Protocol Handler (also works for Silvelight or Xbap)

    So if your goal is to create a protocol handler so that you can create a link with some data in it, click on it and have your clickonce, silverlight or xbap application open up and react to the given data in the link... this is how you do it. As a matter of semantics - you probably know an xbap IS a clickonce deployed application - xml browser application. Actually the application manifest is almost identical to any other clickonce deployed application except that it has an additional few sections indicating to launch in a browser. All three of these will work using this technique though there may be slight variations necessary. I'll cover the more tricky parts that I ran into.

    Protocol Handler
    So let's say you've defined your protocol as MYPROTOCOL. when you normally open a webpage you type in http://whatever - but once your protocol is registered you would type in MYPROTOCOL://whateverarguments and it will execute your deployed application passing the argments specified. You can type that into Vista's start search, or into the browser - or even create a link in an email. Perhaps you will include the ID to some data element and when your application opens it will launch the appropriate UI to load that data based on the ID. This is the scenario I'll be describing - not search protocols or other implementations.

    Approach
    When the user clicks your new custom link it will execute a bootstrapper passing it the command line arguments. That bootstrapper will in turn execute the URL for your clickonce (or silverlight or xbap) deployed application passing the command line arguments as URL parameters. If you were to try to execute the local installed version of your clickonce exe  - you will find that it does not execute under the proper permisisons designated by the certificate you used to sign it. The only way to reliably ensure that your application executes under the correct permissions is to launch the URL and pass querystring parameters to it.  Henceforth I'll refer to all of these (clickonce, silverlight, xbap) as simply "application".  Note: there is a nifty way to keep a single instance of your application even if they click the link multiple times... however as that applies only to clickonce and not to the other application types I won't cover that here. Tip: look at using the VB libraries in your C# library. Otherwise - each link click will open a new instance.

    So here's the task break-down:
    1)
    Configure your application to accept querystring parameters.
    2) Modify the protocol handler bootstrapper (download included) for your application url.
    3) Create an
    MSI installer to register your protocol and install the bootstrapper... (yes - you need to install something on the user's client machine!)

    Configure your application to accept querystring parameters
    The first step is to prepare your application to receive and act on these querystring parameters. You will want to set that up and test it out first. In the end clicking on a link such as http://mydeploymentserver/MyApplicationFolder/MyApplication.application?param1=foo¶m2=bar  should open your application and do whatever you want it to do.

    There's ton's of articles out there detailing how to do that customized per application type - so I won't regurgitate but instead point you in the right direction...
    > For clickonce check out this article
    here.
    > For xbaps check out this article
    here.
    > For silverlight check out this article
    here.

    Protocol Handler Bootstrapper
    Ok so you've got that first part working now, right? Pretty cool, huh? At this point you may be asking yourself why in the world do I even need a protocol handler? I could just use the full link to do whatever I need and WITHOUT requiring the end user to install anything on their client machine. That's absolutely true - you could and if you don't need any of the advantages listed below then that's what I suggest you do.

    Advantages of the protocol handler vs. using the full application url + querystring params directly:
    1) The URL data doesn't change per deployed environment.
    > This one was a big deal for us. We have a lot of test case data pointing to links such as OurProtocol://id=123 that we didn't want to have to change the data per environment url (dev, smoke, test, uat, etc).
    2) The user can type a much shorter entry into Start or Browser (such as openMe:\\id=123 instead of http://www.whatever.com?id=123. ) 
    3) You can piggy back on this to install different desktop shortcuts that will open your application to particular given states.

    Ok - so you've weighed the pros and cons and still want the protocol handler. :) Your bootstrapper will convert the arguments given into a url and launch your browser with the given URL.  See the full solution here.

    Register your Protocol
    You have a few options here. In the end you will want to have an addition to the registry that has the path to your ProtocolBootstrapper.exe and the cmd args - as shown below. Note - if you need to bypass some security restrictions use the "runas" instead of the "open" as shown in the second example below. You could create a .reg file and then execute that with elevated permissions directly from your clickonce application (that's what we did) but that won't work for Silverlight and Xbap. The better approach is to put your new ProtocolBootstrapper.exe into a new MSI that will also update the user's registry with the necessary new keys - then have the users that want to enable this functionality install the MSI.

    For articles on creating an MSI see
    here, here and here!

    Example Registry Entry

    [HKEY_CLASSES_ROOT]
    [YourProtocol]
    (Default) = "URL:Your Protocol Description"
    URL Protocol = ""
    [shell]
    [open]
    [command]
    (Default) = "c:\whereever\ProtocolBootstrapper.exe "%1""

    [HKEY_CLASSES_ROOT]
    [YourProtocol]
    (Default) = "URL:Your Protocol Description"
    URL Protocol = ""
    [shell]
    [runas]
    [command]
    (Default) = "c:\whereever\ProtocolBootstrapper.exe "%1""



     

     

     

     

  • Shared Resources XAML Intellisense

    [ I'll provide a full solution download to anyone interested ] 

     Our Goals were:

    1) Use images in XAML syntax like this:

    <Image Name="imageSave" Height="16" Width="16" Source="ui:Images.ico_save_16.png"/>

    2) Break on invalid image references at COMPILE - not at runtime.
    3) Automatically add new when new images are copied into project.
    4) Share resources within solution across projects.
    5) Get intellisense for images from different projects in the same solution where possible (currently only in the codebehind - but the xaml editor will eventually provide intellisense here too).
    6) VS 2008

     

    _________________________________________________________

    We created a separate "Resources" class library. In that class library we created an Images folder and under that an "ico" and "png" folders with all our images. Not added to "Resources" or "settings" as these generate only internal strongly typed - you need public.

    Step 2:

    Inside that class library create a text template - I called it Generator.tt. This text template will scan your directory of files and output something like this (below). We have two sub properties "ico" and "png" for the same resource... but you don't have to have that complexity.

    // <auto-generated>
    public
    static class Images
    {

    public static class ico_user_16
    {

    public static BitmapFrame png
    {
           get { return ResourceLocator.GetImageSource("ico_user_16.png"); }
    }

    }//end ico_user_16

    #endregion

    ------------------------------------------

    The only really tricky part in creating the tt file was figuring out how to find the current directory to scan the project files...

    string icoPath = this.Host.ResolvePath(@"Images\ico");

    Now you can add references to that "Resources" class library from any project in your solution and get static resources in your xaml files... and share them across projects. As you add new images to your resource library simply save your Generator.tt file to re-generate your static resources.

    Enjoy!!! 

     

     

     

     

     

     

     

     

     


     

     

     

     

  • AJAX, XBAP, Silverlight

    Ramblings (in response to a question)…

     

    I would have to know a lot more about his requirements before making a recommendation. In particular – what are the skill sets of his existing resources?

     

    I’m guessing the primary things you are looking for are ease of deployment for first-time use as subsequent updates. Performance over high latency. Resiliency – say when your internet connection goes down. Client-server transactions. Etc..

     

    ·         High performance over high latency networks comes from asynchronous transactions and transferring as little data as possible per transaction. Compression and other factors also come into play.

    ·         Optimum resiliency/stability typically translates to a form of local storage. If you are able to queue transactions locally and securely - you can re-try in the event that the network is down – otherwise your transaction data may be lost.

     

    For us – those two factors eliminated asp.net / ajax. Secure local storage isn’t an option. And - even with maximum caching enabled – in a sizable application most transactions still contain UI rendering information in addition to the data – eg html – that has to be downloaded to the client (browser). Also Silverlight’s or XBAP’s use of the CLR is much faster than the browser’s javascript engine (by about 42%).

     

    Let’s start with XBAP… XBAP (or Xml Browser Application) really just refers to a standard WPF application deployed via clickonce over the internet – and hosted within the browser. Clickonce, of course, allows for incremental updates – so most of the time you don’t need to re-download your presentation layer.

     

    I’ve seen blogs and info stating a variety of limitations inherent in XBAP such as calling web services, opening new windows, talking to the registry and/or local files… but from our experience I know all of those things are possible with an XBAP. Those are not limitations inherent in the technology. So long as your XBAP application and deployment manifests are signed with a certificate that resides in your Trusted Root certificates then you can do pretty much anything with an XBAP application. If you don’t need that much power – you can still write files to isolated storage and go with a less trusted cert – giving you the resiliency.

     

    The cons of using xbap vs. silverlight is that you require the end user to trust your certificate (typically a prompt) and – the big “and” – they have to be on the windows operating system and download the prerequisite version of .NET 3.0 (or greater). The bootstrapper is only around 2.5mb – but the entire framework is around 50mb! Imagine how long that takes to install with 300ms latency. Once they have that installed – as your application advances be prepared for upgrades (3.5, etc).

     

    Silverlight provides capabilities to use Web Services, Isolated Storage and other features but with a small  under 5mb initial download, cross-platform capabilities and most of the core features that come in the WPF libraries – hence the name “WPF/e”.  

     

    Depending on your resources - if they are C# / web developers – then Silverlight may be the best option for you. Silverlight 2.0 due out this month - is releasing a whole bunch of new controls – mirroring all the standard control in the WPF library. (eg textbox, combobox, etc) – making development in visual studio fairly easy. It isn’t just a “flash” replacement anymore. When *matured* – it’s a substantial new technology.

     

    I’m currently investigating Silverlight 2.0 for migration of our xbap/clickonce WPF application to Silverlight 2.0.

     

    -          Rob.

     

    _____________________________________________________________

      

    Hi Rob,

     

    One of my friend has the following requirement,

     

    ·         Thin client

    ·         Real time update of data from server to client (Since server push is not possible, he is thinking of AJAX. There are commercial frameworks like COMET available that gives the server push which he  will not be using )

    ·         Performance (Stability and responsiveness are preferred over jazzy look and feel – say 3d transformations)

     

    He is looking at the following options:

    ·         ASP.net + AJAX

    ·         MS Silverlight

    ·         XBAP

    ·         Smartclients with CAB framework

     

    Each has its own advantages and disadvantages. It is hard to decide as he does not have visibility into the roadmap for some of these options. Can you suggest something on this?

     

    In fact “Adobe Flex” supports all these requirements except the fact that integration with .net framework is not available. So he had to drop the idea of using Flex!!!!

  • Download Pictures from your Cell Phone via Bluetooth

    If you have a bluetooth enabled laptop and a bluetooth enabled cellphone you may be able to download the pictures from your phone to your laptop via bluetooth... EVEN if your cell phone provider says it isn't possible (as in my case).

    Perhaps they direct you to use their picture place service and to message your phone's images to that picture place. The down-side of this approach is that you loose resolution, it takes forever, and it costs a fortune!

    This weekend I discovered a nifty free application that allows me to download my picutures from my camera phone faster, wireless via bluetooth, without loosing picture resolution - and for FREE!

    Here's what you need to do:

    1. Pair your phone to your laptop via bluetooth. (instructions for vista)
    2. Download and install the bitpim exe from http://www.bitpim.org
    3. Once Installed start it up.  You should now see a screen like:

    BitPim Setup

    You can walk through the wizard to setup your phone. For my model phone - I found that the images were downloaded as part of the "wallpaper" download.

    In addition - you can find (or create) ringtones and upload them to your phone via bluetooth, wireless and for FREE.

    This is a great little jem of a find.

    Bitpim after

  • SQL 2005 - XML parsing... illegal xml character

     

    You may run into an error when using SQL 2005 and a .NET 2.0 aspx or windows client UI.

     

    Perhaps you’ve encoded your xml – you are using stored procedures and proper sqlParameters and everything – yet you still run into this exception.

     

    Example repro:

    DECLARE @xml xml

    SET @xml = N'<A>&#x2;</A>'

    SELECT @xml.query('<A>{substring(.,1,1)}</A>')

     

    XML parsing: line 1, character 1, illegal xml character

     

    This is because SQL 2000’s xml parsing was based on MSXML 3.0 – and SQL 2005’s xml parsing is based on MSXML 6.0. The rules have tightened up a bit. You may be able to store and work with xml characters in your .NET UI layer (ASPX or C# Windows Client) – but once you try to INSERT them you will get this exception.

     

    As of SQL 2005 only W3C Compliant characters are allowed in XML. The range of valid XML characters as defined by W3C XML Language specifications 1.0 are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF].  Any characters outside of that range (as in the example above) may actually be INPUT by the user, stored as xml in your client – but will throw an exception when the INSERT command is executed in your SQL server.

     

    One answer to this problem (maybe not the most elegant) is to scrub user input via the method shown below:

     

     

       

     

        /// <summary>

        /// IsW3CCompliant

        /// http://w3c.org

        /// The valid XML characters and character ranges (hex values) as defined by the W3C XML language specifications 1.0:

        /// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

        /// </summary>

        /// <param name="c"></param>

        /// <returns></returns>

        static private bool IsW3CCompliant(char c)

        {

          int charInt = Convert.ToInt32(c);

          return charInt == 9 || charInt == 10 || charInt == 13 || (charInt >= 32 && charInt <= 55295) || (charInt >= 57344 && charInt <= 65533) || (charInt >= 65536 && charInt <= 1114111);

        }

     

     

     

        /// <summary>

        /// Scrub Xml ensures that each character is W3C compliant.

        /// This is a major performance hit. . .

        /// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

        /// </summary>

        /// <param name="xmlStr"></param>

        /// <returns></returns>

        static internal string ScrubString(string xmlStr)

        {

          if (xmlStr == string.Empty || xmlStr == null)

            return xmlStr;

     

          string pattern = @"[^\w\.@-]";

          StringBuilder strB = new StringBuilder(xmlStr.Length);

     

          //-- If there are no special chars just return the original (99%)

          Regex regex = new Regex(pattern);

          if (!regex.Match(xmlStr).Success)

            return xmlStr;

     

          char[] charArray = xmlStr.ToCharArray();

          for (int i = 0; i < charArray.Length; i++)

          {

            if (IsW3CCompliant(charArray[i]))

            {

              strB.Append(charArray[i]);

            }

          }//for

     

          return strB.ToString();

        }

     

     

     

     

      /// <summary>

      /// XmlTextWriter override that scrubs the attributes

      /// </summary>

      public class MyXmlTextWriter : XmlTextWriter

      {

        /// <summary>

        /// MyXmlTextWriter scrubs attribute values. Constructor just calls base.

        /// </summary>

        /// <param name="tw"></param>

        public MyXmlTextWriter(System.IO.TextWriter tw) : base(tw) { }

     

        /// <summary>

        /// MyXmlTextWriter scrubs attribute values. Constructor just calls base.

        /// </summary>

        /// <param name="filename"></param>

        /// <param name="encoding"></param>

        public MyXmlTextWriter(string filename, System.Text.Encoding encoding) : base(filename, encoding) { }

     

        /// <summary>

        /// MyXmlTextWriter scrubs attribute values. Constructor just calls base.

        /// </summary>

        /// <param name="w"></param>

        /// <param name="encoding"></param>

        public MyXmlTextWriter(System.IO.Stream w, System.Text.Encoding encoding) : base(w, encoding) { }

     

        /// <summary>

        /// This class scrubs the attribute value - the sole

        /// reason for this class.

        /// </summary>

        new public void WriteAttributeString(string localName, string value)

        {

          base.WriteAttributeString(localName, XmlHelper.ScrubString(value));

        }

     

        /// <summary>

        /// This class scrubs the attribute value - the sole

        /// reason for this class.

        /// </summary>

        public void WriteAttributeStringRaw(string localName, string value)

        {

          base.WriteAttributeString(localName, value);

        }

     

      }//MyXmlTextWriter