Jesse Johnston
{ ironic tagline here }

Windows Azure: Where is my stuff?

Wednesday, 3 August 2011 06:17 by jesse

So you’ve deployed an application to Azure.  If you login to the deployment with Remote Desktop, your first question might be “Where is my application installed?”.

There are three disk drives in the deployment.

  • Drive C: contains your local storage folders
  • Drive D: is the operating system
  • Drive E: contains your application files

Local Storage Folders

In C:\Resources\Directory, you will see each of your local storage folders.  These are prefixed with a generated Id.  Note that you will not have permissions to open any of the files in these folders unless you added permissions via a startup task.  See my previous post for an example of how to do this.

Your Deployment

Your uploaded application files are located in E:\approot.  You can refer to this location in your code with the RoleRoot environment variable (RoleRoot will resolve to “E:\”, so you’ll need to append “approot”).

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Tags:  
Categories:   .NET | Windows Azure
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Windows Azure Deployment Tips & Tricks

Wednesday, 3 August 2011 05:48 by jesse

I’ve run into a few gotchas when deploying to Azure.

  • Missing DLLs. Not all “system” libraries are included in the Windows Azure run-time environment.  If you use any of these, make sure to mark them as CopyLocal=true in your project.  The one I always forget is EntityFramework.dll.
  • Folder permissions.  If you add local storage folders to your deployment, you might be surprised to find that when logged in to the deployment machine with Remote Desktop, you won’t have even read permission to files in local storage folders.  Fortunately, you can easily add a startup task to grant permissions.  In my deployments, I use a batch file to launch a PowerShell script to do this.  The batch file (fixPermissions.cmd) looks like this:

    powershell -ExecutionPolicy Unrestricted .\FixFolderAccess.ps1

    The PowerShell script (FixFolderAccess.ps1) looks like this:

    Add-PSSnapin Microsoft.WindowsAzure.ServiceRuntime
    
    while (!$?)
    {
        echo "Failed, retrying after five seconds..."
        sleep 5
    
        Add-PSSnapin Microsoft.WindowsAzure.ServiceRuntime
    }
    
    echo "Added WA snapin."
    
    $localresource = Get-LocalResource "myLocalStorageFolderName"
    $folder = $localresource.RootPath
    
    $acl = Get-Acl $folder
    
    $rule1 = New-Object System.Security.AccessControl.FileSystemAccessRule(
      "Administrators", "FullControl", "ContainerInherit, ObjectInherit", 
      "None", "Allow")
    $rule2 = New-Object System.Security.AccessControl.FileSystemAccessRule(
      "Everyone", "FullControl", "ContainerInherit, ObjectInherit", 
      "None", "Allow")
    
    $acl.AddAccessRule($rule1)
    $acl.AddAccessRule($rule2)
    
    Set-Acl $folder $acl
    
    echo "Done changing ACLs."
  • Startup tasks.  When adding a startup task, you need to do two things: first, add the task to the role in your .csdef file.  This will look something like this:

      <WorkerRole name="MyWorkerRole">
        <Imports>
          <Import moduleName="Diagnostics" />
          <Import moduleName="RemoteAccess" />
        </Imports>
        <Startup>
          <Task commandLine="startup.cmd" executionContext="elevated" taskType="background" />
        </Startup>
      </WorkerRole>

    The execution context can be “elevated” if the command you’re running requires administrative privileges, or “limited” to use the same privileges as the role itself.  The task type can be “simple”, where other tasks (and the role itself) are not started until the task finishes, or “background”, in which other tasks and the role can be started before the task completes.  A third type, “foreground” allows other tasks to start before it is finished, but the role is not started until the task finishes.

    The second part of creating a startup task is to create the batch file that is referenced in the <Task> element above.  In this case, it is startup.cmd.  It is essential that you save this file without a byte order mark.  To do this from Visual Studio, when saving the batch file, use Save As, and select the option Save with Encoding from the Save button dropdown.  Select Unicode (UTF-8 without signature) – Codepage 65001.  If you prefer, you can just create the batch file with Notepad, which will also save it without the offending byte order mark.

    A final note about startup tasks:  If you use PowerShell in a startup task, you need to set your ExecutionPolicy to allow unsigned scripts (as shown in the example above: -ExecutionPolicy Unrestricted).  This is only supported in PowerShell 2.0, which means that you need a Windows Server 2008 R2 run-time environment.  This is not the default in Azure.  To enable this, set the <ServiceConfiguration> tag in your .cscfg file to specify osFamily=”2”.  This requests the Windows Server 2008 R2 environment instead of the default Windows Server 2008 SP2.
  • Custom performance counters.  They are supported in Azure.  You do have to create the performance counter category in an elevated startup task, as the role itself does not have the required permissions.
  • Can a Worker Role handle HTTP requests?  Sure it can.  Just make sure that you add an inbound rule to the Windows Firewall allowing traffic on port 80.  Note that this rule will be deleted if you stop the deployment or reboot

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Tags:  
Categories:   .NET | Windows Azure
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

PDX Code Camp Session: WP7 Tips & Tricks

Sunday, 23 May 2010 15:18 by jesse

Chow I presented the Windows Phone 7 Tips & Tricks session with Allen Newton yesterday at Portland Code Camp.  Good times.  In our talk we showed a sample application "PDX Chow" that demonstrates a number of phone development concepts:

  • MVVM architecture with Laurent Bugnion's MVVM Light
  • Panorama control
  • Inversion of Control / Dependency Injection
  • Navigation using commanding and context
  • Page orientation events
  • Accessing phone features with tasks
  • ApplicationBar wrapper class that is fully Blendable and supports attached behaviors
  • Application life-cycle events
  • Accessing WCF services

The slide deck and code for the sample app are available on the downloads page.  Enjoy!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

System.ServiceModel.ProtocolException: An HTTP Content-Type header is required

Wednesday, 19 May 2010 16:29 by jesse

The full exception message is “An HTTP Content-Type header is required for SOAP messaging and none was found.”.

If you’re writing a WCF service that returns Entity Framework entities, you may run into this error in your client application.  To correct it, open your EDMX file in the service project and change the Lazy Loading Enabled property to False.

It makes sense that related entities can’t be lazy-loaded after the query results have been returned to the client, but the error message doesn’t make that super-obvious.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Tags:   ,
Categories:   .NET | WCF | EF
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Silverlight 3 Navigation: My HyperlinkButtons don’t work!

Sunday, 17 January 2010 15:30 by jesse

The navigation framework of Silverlight 3 is great.  The URI mapping and browser history support add a lot of value.

When upgrading a Silverlight 2 site to use Silverlight 3 with navigation, I was surprised to see that all of my HyperlinkButtons that referenced external URLs were failing!

For example, a button with this XAML:

<HyperlinkButton Content="Microsoft" NavigateUri="http://www.microsoft.com"/>

when clicked yields this:

image

It turns out that once your HyperlinkButton is inside of a navigation frame (which it will be once you add navigation support to your application), you need to set the TargetName property of the button.  To preserve the Silverlight 2 behavior where the referenced URI loads in the same browser window, use “_self” as the TargetName:

<HyperlinkButton Content="Microsoft" NavigateUri="http://www.microsoft.com" TargetName="_self"/>

You can also use “_blank” to open up the page in a new browser window.

When using a HyperlinkButton to navigate to a Silverlight page internal to your application, TargetName should reference the name of the navigation frame:

<navigation:Frame x:Name="ContentFrame" Source="/home">
  <navigation:Frame.UriMapper>
    <uriMapper:UriMapper>
      <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
      <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
    </uriMapper:UriMapper>
  </navigation:Frame.UriMapper>
</navigation:Frame>
 
<HyperlinkButton NavigateUri="/about" TargetName="ContentFrame" Content="About Us"/>
 

HyperlinkButtons fixed!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Categories:   .NET | Silverlight
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

.NET 101

Monday, 26 October 2009 05:10 by jesse

If you find yourself wanting yourself to share some C# brilliance related to…images

  • The difference between Object.Equals() and ==
  • How string comparison is an interesting special case
  • Why class instance memory is not necessarily reclaimed when an instance goes out of scope
  • Which of Stream.Close() and Stream.Dispose() should be called (or both)

Please remember that it is not 2001.  Everyone knows these things (unless you’re in a .NET 101 class).  If you don’t know these things…may I suggest .NET U?

Seriously, though – how about something interesting like harnessing the power of IObservable<T>?  Bring on the new!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

Doing the Dishes

Friday, 2 October 2009 03:13 by jesse

You DO want to do more than the minimum don't you?While washing all of the coffee cups left in the office sink by others this morning, I was reminded of a lot of code I’ve seen lately.

How often do you open up a piece of code in Visual Studio to find something implemented in a completely ad hoc way, or only half done?  Swaths of code commented out, TODOs sprinkled throughout, all sorts of unrelated concerns mixed in.

These are dishes in the sink.  Someone went home early to get their weekend started and left the work for someone else to do.  This attitude can’t be tolerated in an organization that wants to win.

When hiring, I always look for people who go beyond the minimum.  These are the people who not only deliver great, complete code, but also mentor, blog, and develop their own works.  People who show up early and leave late because they love what they do and have a hard time walking away.  People who wear more than 15 pieces of flair.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Where are the recent items in my Windows 7 jump list?

Thursday, 1 October 2009 11:49 by jesse

I just started adding support for the Windows 7 taskbar jumplist to my WPF application, using the excellent .NET wrappers in the Windows API Code Pack.

After creating the jump list, file selection via the Windows common file dialogs should automatically cause entries to appear in the Recent section of the jump list.

But no.  What's going on?

It turns out that everything is working as expected.  However, you need to have the "recent items" checkbox enabled for the taskbar:

 

 
Once clicked, the Recent items appear on the jump list. 
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Categories:   .NET | WPF
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Scrolling TextBox in WPF

Thursday, 1 October 2009 03:03 by jesse

If you put a TextBox inside a ScrollViewer, the TextBox will take as much width as it needs, even if you set TextWrapping to Wrap.  That means that a long line of text will just stretch out to the right, beyond the right edge of the ScrollViewer, instead of wrapping.

Fortunately, you can bind the Width of the TextBox to the ScrollViewer ViewportWidth.  This makes the text wrap at the right edge of the ScrollViewer.  If you hide the horizontal scrollbar, you get just what you'd expect - vertical scrolling and horizontal wrapping.  This also allows the ScrollViewer to participate in a flow style layout and still have the text wrap correctly.

<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">

<TextBox IsReadOnly="True" FontSize="14" TextWrapping="Wrap" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=ViewportWidth}"/>

</ScrollViewer>

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Categories:   .NET | Silverlight | WPF
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

code2plan Filters

Monday, 30 March 2009 02:31 by jesse

Yesterday Denis and I released a new version of code2plan that includes a couple of long-awaited features: filter and search.

We've had filters for some time, but they weren't fully functional.  Our new release supports some great new filtering capabilities:

  • Filters are persistent.  You can save your filters by name, and they appear in the filters popup for the appropriate work items page.  A filter is always associated with a specific kind of work item, like tasks or stories.  The filter selected for a work items page is also remembered, so if you select the "Backlog" filter on the stories page, you'll still be looking at the backlog when you return to that page later.
  • Filters can be shared.  Just like work items, if you create a filter, all the other users in your team can see and use it.  Unlike work items, filters can also can be private, so you can have your own special set of filters that is visible only to you.
  • Filters can be organized.  For each work item type, there is a list of all filters.  You also have a list of favorite filters for each work item type that is specific to you.  You can add and remove filters to this list, and move filters up and down in the list.
  • Filters have new special values.  Almost all work item properties can be filtered on.  Most properties are standard types, like string, decimal, and date.  You can filter on specific values for these types (including "not set").  Date properties can also be compared to special values "today", "in the future", and "in the past".  These values are special because they are always evaluated at the moment the filter is run.  That means that your filter results will automatically change over time as existing date values move into the past.  Work item properties that refer to iterations can be compared to the special value "current iteration", which refers to whichever iteration is selected on the dashboard.  Finally, the owner property can be compared to the "logged in user", which refers to whoever is currently logged in.  All this means that it is easy to construct a filter like "my iteration tasks" which looks for tasks owned by the logged in user for the current iteration.  This filter will always be relevant regardless of who is logged in or which iteration is current.
  • Predefined filters.  We've included a bunch of filters out of the box to get you started.  These filters automatically populate the favorites list on each page.

Note that the Dashboard and Stories pages no longer implicitly filter on current iteration.  You'll see all tasks and stories unless you select a filter.  The iteration combo box on the Dashboard still sets the current iteration, but this is only used for the "current iteration" special value in filters, and for the burndown chart.

A browser-style search box has also been added to each page.  Here you can enter one or more words, which will be searched for in the work item name, description, and comments properties.  All of the words must be found for a work item to match, but they can be found in any of the properties mentioned.  On the people page, the search is performed on the login, first name, last name, and email properties.

Note that when a filter is applied, search will only return results that are also included in the filter.  So, if you have a filter selected for open defects only, a search won't return any closed defects.

There are a few other enhancements and bug fixes.  Denis spent some time revamping the color schemes for our users on Windows XP (you've reported that the colors weren't the best).  See the release notes for all the detail.

I hope you like the new version - go to www.code2plan.com and download it now.  code2plan is free!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed