• 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

  • 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!!! 

     

     

     

     

     

     

     

     

     


     

     

     

     

  • 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""



     

     

     

     

  • 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!

     

  • 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.