Posts
27
Comments
59
Trackbacks
0
Friday, October 09, 2009
Windows Azure Dev Fabric and the PathTooLongException

I’ve been working on converting a complex, distributed, real-world application to the cloud.  It’s been an exciting journey, but also one filled with little gotchas.  One such gotcha was a failure on startup of dev fabric when running a web role containing a series of WCF services.  The specific exception I got ended up being a PathTooLongException.

I dug into the problem and discovered that the folder hierarchy for the ‘deployed’ artifacts running on the local dev fabric is crazy long.  As my project artifacts were deployed, the dev fabric was throwing the PathTooLongException when it ran into an assembly whose full path exceeded the OS limit.  Because of the length of the root dev fabric deployment path, the flexibility of naming your web/worker roles and dependent assemblies is significantly limited.  Here’s what I found:

The root path of deployments made to dev fabric is something like (on Win 2008, anyway):

C:\Users\{username}\AppData\Local\dftmp\s0\

This isn’t crazy (yet), but each deployment consists of a series of hierarchical folders depending on the roles.  Within each role, dependent assemblies are located still deeper within the folder structure.  So, as an example, one of the assemblies might be located at (this was an actual path; names changed to protect the innocent):

C:\Users\{username}\AppData\Local\dftmp\s0\deployment(27)\res\deployment(27).{ServiceDefName}.{RoleName}.0\AspNetTemp\aspNetTemp\root\07ac5e60\bd64b387\assembly\dl3\2cbe1cb5\591b1f0f_1842ca01\{AssemblyName}

This is crazy long!  Without the username, service definition name, role name, and assembly name, I’m already up to 156 characters.  Considering the path length maximums are 248 for the folder name, and 260 for the complete filename, we’re already pretty far along.

Now, consider this:  sometimes, you use 3rd party assemblies, whose names can’t easily be changed.  Take, for example, one of the Enterprise Library assemblies: Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF.dll.  This just happened to be one of the assemblies being used by my WCF services.  Taking that assembly name into account, that’s chewing through another 69 characters, leaving just 23/35 characters total for the username, service definition name, and role name before hitting the directory/path limits, respectively.  That’s not a lot of characters, especially when you consider that some usernames are a concatenation of first and last, such as david.barrett.  Another 13 characters lost.

How do you minimize these tokens?

The ServiceDefName token in the path above can be modified by manually updating the value in the ServiceDefinition.csdef and ServiceConfiguration.cscfg without any effect on the code (in other words, you don’t have to actually change the name of the project or folder:

<ServiceDefinition name="A" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">…

The RoleName is taken from the project name.  This is the same name that shows in Visual Studio, and is not necessarily the name of the project file itself.  I typically name projects (and assemblies) with a ‘namespace’ flavor, such as Company.System.Subsystem/Feature.  In this case, I can’t afford that length, so I had to shorten it something like Svcs after creating the project initially as Company.System.Subsystem.  Blech.

posted @ Friday, October 09, 2009 3:55 PM | Feedback (0)
Monday, October 05, 2009
Call to iPhone Devs for KeePass port

If you’re an iPhone user like me, and you also use KeePass on Windows for password management, you’ve probably noticed the gaping hole in KeePass availability for the iPhone.  There was supposedly a German fellow building a port for the iPhone (http://ikeepass.de/), but after several failures to get the app into the App Store, the project seems to have died.

There are alternative vault apps out there for the iPhone, but I have yet to find a decent one that I like that integrates well with what I already have – KeePass.

I don’t have the facilities to develop an iPhone app (thanks, Apple, for excluding anyone on a Windows platform), but would love to work with someone who has a Mac to manage the work effort.  My plan is to develop a KeePass plugin that syncs the iPhone over WiFi, so I would be happy to do that part.

So, iPhone developers out there – who wants to step up and fill this void?  Feel free to contact me via this forum or leave a comment.

UPDATE (10/7/2009):  iKeePass.de breathes life anew.  A new submission to the app store.  We’ll see what happens.

posted @ Monday, October 05, 2009 12:56 PM | Feedback (2)
Monday, August 03, 2009
Conferencing Add-In for Outlook: “An error occurred while executing this command”

I experienced this error recently and spent an eternity trying to resolve it.  I finally found the solution to my problem and wanted to document it for others.

For me, the issue only appeared when I tried to invite people to a scheduled meeting.  Under normal circumstances, blank (no invitees) scheduled meetings worked fine.  Ad-hoc meetings worked fine.  Some invitees worked, but others did not.  When an invitee caused the issue to appear, this message would be displayed either when I saved/sent the meeting, or tried to set an invitee as a meeting leader.

It turned out to be caused by the format of the invitee information.  Typically, on an Exchange-based email network, your global address book contains all the people within your company.  Sometimes, emails will get sent around that results in employee names being displayed something like My Name <my.name@company.com> instead of just My Name.  These entries can get cached in a frequent recipient list that will pop down when entering addressees.

Well, it turns out this format causes the Conferencing Add-In to barf.  When entering recipients into a LiveMeeting request, entries in this format (as opposed to the usual Exchange My Name format) will cause something somewhere to fail, resulting in this message.  Keep in mind that the name will look correct in the To: field, even though “behind the scenes” it’s actually the lengthy format above.

To resolve, either select a user from the Global Address Book when entering attendees or remove the entry for the cached list by hitting Ctrl-Delete while the name is highlighted in the list.  Then enter a name, force a lookup on the user (“Check Names”), and all should be well.

posted @ Monday, August 03, 2009 12:18 PM | Feedback (1)
Tuesday, May 12, 2009
Azure Local Storage Endpoints

I’m constantly having to search for the local development storage endpoint Uris when I create a new Azure storage project from scratch, not to mention the account name and shared key, so I’m posting them here for my own reference.  Hopefully others will also find it useful.

   1: <ConfigurationSettings>
   2:         <Setting name="AccountName" 
   3:             value="devstoreaccount1"/>
   4:         <Setting name="AccountSharedKey" 
   5:             value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
   6:         <Setting name="BlobStorageEndpoint" 
   7:             value="http://127.0.0.1:10000/"/>
   8:         <Setting name="QueueStorageEndpoint" 
   9:             value="http://127.0.0.1:100001/"/>
  10:         <Setting name="TableStorageEndpoint" 
  11:             value="http://127.0.0.1:10002/"/>
  12: </ConfigurationSettings>
posted @ Tuesday, May 12, 2009 9:40 AM | Feedback (0)
Tuesday, March 10, 2009
Team Build: Part 1

I’ve had the fortune of being involved in some pretty complex and elegant Team Build configurations.  I’ve started to blog about individual points several times, but ended up figuring that I should instead write a series of posts about common goals and general Team Build approaches.  I can’t take credit for all this content.  Some I’ve developed over time, some I’ve learned from others on the web, and yet other stuff I’ve learned from co-workers.  That said, here we go with Part 1.

General Approach

Every person has their personal preference, and this is typically taken to the nth degree with programmers.  What follows are my personal preferences.  Yours may vary.

First, I like to separate any custom team build stuff from the default TFSBuild.proj file.  I’ll update properties already existing in that file, or available via the Microsoft.TeamFoundation.Build.targets file, directly in TFSBuild.proj.  But all my custom stuff exists in a separate file, or files.  For example, I’ll aggregate all my custom tasks into a CustomTasks.targets file, and import that at the bottom of TFSBuild.proj:

   1: <ItemGroup>
   2:     <!--  ADDITIONAL REFERENCE PATH
   3:  The list of additional reference paths to use while resolving references. For example:
   4:  
   5:      <AdditionalReferencePath Include="C:\MyFolder\" />
   6:      <AdditionalReferencePath Include="C:\MyFolder2\" />
   7: -->
   8: </ItemGroup>
   9:  
  10: <!-- Add our custom target overrides -->
  11: <Import Project="Environment.proj"/>
  12: <Import Project="CustomTasks.targets" />
  13:  
  14: </Project>

Here, we’ve imported the CustomTasks.targets file that contains all of our customizations, and we’ve also imported an Environment.proj file that contains metadata about the environment to which we typically deploy this build configuration.  In this way, we can create additional build for additional environments, and only need to change the Environment.proj file.

Within the CustomTasks.targets file, I declare any custom MSBuild tasks I need, as well as define my overrides and custom targets.  (See http://msdn.microsoft.com/en-us/library/aa337604.aspx for a list of overridable team build targets).  An example skeleton is as follows:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
   3:  
   4: <UsingTask TaskName="XmlMassUpdate" AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" />
   5: <UsingTask TaskName="Attrib" AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" />
   6: <UsingTask TaskName="XmlFile.GetValue" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft.Sdc\Microsoft.Sdc.Tasks.dll" />
   7: <UsingTask TaskName="XmlFile.SetValue" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft.Sdc\Microsoft.Sdc.Tasks.dll" />
   8:  
   9: <Target Name="BuildNumberOverrideTarget">
  10:   <CallTarget Targets="CalculateCustomBuildNumber" />
  11: </Target>
  12:  
  13: <Target Name="GenerateDocumentation">
  14:   <CallTarget Targets="CreateCustomDocumentation" />
  15: </Target>
  16:  
  17: <!-- Custom targets removed for brevity. -->
  18:  
  19: </Project>

For custom build tasks, I typically rely heavily on the Sdc and MSBuild Community tasks (http://www.codeplex.com/sdctasks and http://msbuildtasks.tigris.org/).  There’s not alot they can’t do, but if you find something, you can always develop a custom task yourself.

Adjusting Application Settings During a Deploy

One of the custom tasks I rely *heavily* on is the XmlMassUpdate task.  There are many scenarios where you want to tweak configuration settings when you deploy to an environment, and this task is perfect for it.  In a nutshell, you provide a set of configuration data (in this case, Xml), and the task dynamically updates/removes/adds the config content to match your desired settings.  I typically embed the configuration directly in the custom build file, but you could also declares this externally.  MSBuild supports including “random” Xml in the build file via the <ProjectExtensions/> node (anything within this content is ignored by MSBuild).  So, using this and the XmlMassUpdate tasks, we can do the following (example only):

   1: <ProjectExtensions xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
   2:   <MyAppConfig xmlns="">
   3:     <configuration>
   4:       <appSettings>
   5:         <add xmu:key="key" key="MyDeployedValue" value="One" />
   6:         <add xmu:key="key" key="MySecondDeployedValue" value="Two" />
   7:       </appSettings>
   8:     </configuration>
   9:   </MyAppConfig>
  10: </ProjectExtensions>
  11:  
  12:  
  13: <Target Name="ConfigOverride">
  14: <Attrib Files="$(SolutionRoot)\MyApp.config" ReadOnly="false" />
   1: <XmlMassUpdate ContentFile="$(SolutionRoot)\MyApp.config"
   2:                        ContentRoot="/configuration"
   3:                        SubstitutionsFile="$(BuildDirectory)\BuildType\CustomTasks.targets"
   4:                        SubstitutionsRoot="/msb:Project/msb:ProjectExtensions/MyAppConfig/configuration"
   5:                        NamespaceDefinitions="msb=http://schemas.microsoft.com/developer/msbuild/2003" />
  21: <Target>

The attrib task is there because, by default, files grabbed from source control to be used during a build are read-only.  You’ll want to check the docs on how to use XmlMassUpdate, but the short of this says (assume you call the ConfigOverride target somewhere else in your build process):

On the file MyApp.config in my solution path, replace/modify content starting at the /configuration node, using the content included in the CustomTasks.targets file (this same file) starting with the node located at Project/ProjectExtensions/MyAppConfig/configuration.  In this case, it will update the appSettings/add node with an “key” attribute of ‘MyDeployedValue’ to have a “value” attribute of ‘One’, and similarly for the second entry.

I use this for all manner of things, from updating configs, to updating project files (they’re just Xml after all), to updating Sandcastle help file docs, to adjusting ClickOnce settings on a deploy.  We’ll see more about these in the next several posts.

posted @ Tuesday, March 10, 2009 4:32 PM | Feedback (0)
Tuesday, February 10, 2009
I Can't Find the Live Framework SDK and Tools Download!

Applied for the Windows Azure Live services CTP and received your token, but can't find the download?  You're not alone.

Following the download links for me, even after I received and entered my token, took me in a circular loop.  That is, it took me into a loop until I actually started to create a Live-enabled cloud app.

Dariusz Parys blogs about this issue, and how to actually get the download links to work in this blog post.  Thanks, Dariusz!

posted @ Tuesday, February 10, 2009 9:24 AM | Feedback (0)
Thursday, January 15, 2009
Denver January 2009 Windows Azure User Group Meeting

The Denver January 2009 Windows Azure User Group Meeting was held on January 13th.  We discussed cloud storage in Windows Azure, including the blob, table, and queue tools.  Thanks for everyone who attended and for making the meeting a success!  For a recap of the presentation and demo material, go see the post at the official site:  www.azureusergroup.com.  While you're there, sign up to be informed of your next local user group meeting!

posted @ Thursday, January 15, 2009 3:07 AM | Feedback (0)
Friday, January 16, 2009
Windows Azure January 2009 CTP Released

For anyone who still hasn't seen the announcement, the January 2009 CTP for the Windows Azure tools were released.  See the official blog post here.  Go grab the latest bits and start leaning Azure today.

posted @ Friday, January 16, 2009 2:57 AM | Feedback (0)
Tuesday, January 27, 2009
VCBuild, BK1513, and Team Build

I ran across this issue while automating a particularly complex build.  It turns out the C++ project was being built twice during the automated build.  Ensuring the build only ran the C++ project once fixed up my problem.

Hope this helps anyone struggling with this combination of issues.

posted @ Tuesday, January 27, 2009 2:55 AM | Feedback (0)
Saturday, November 29, 2008
Network Media uPnP

I wrote last time about setting up my Linksys router with DD-WRT and sharing my media on the local network with a USB storage drive.  I had intended to also install a Universal Plug and Play (uPnP) media server on the router, but never could find a good media server that ran on embedded Linux.  I tried uShare, and it worked OK, but only with my pictures.  I also attempted to run TwonkyMedia, but never could get it installed on the router.  A friendly request in the Twonky Vision forums went unanswered, and others in the same forum lamented about the lack of support for a pay product.  Oh well.  I moved on.

So I turned to TVersity, a free uPNP media server for Windows.  The unfortunate side effect is that I'll have to leave my laptop running to serve up content, but hey, my opinion was that if it worked, it is a small price to pay.  I installed it, and it simply ... worked.  The management interface is clean and fairly easy to use.  While the initial media cataloging process took several hours (quite a bit longer than I had expected), once it was done, refreshes didn't take much time at all.  I'm now sharing local media, network media, and Internet media (podcasts, Flickr images, Internet video, etc.), all to any uPnP devices on my network (of which the Xbox 360 is the intended target).

I'm also waiting for MediaPortal version 2, which will include uPnP support in addition to the already-existing HTPC-type features, like tuner recording and program playback.  MediaPortal is also open source and written in .net, both features that I find extremely attractive.

posted @ Saturday, November 29, 2008 11:38 AM | Feedback (0)
News
Comment and opinions are my own and do not reflect on my company in any way.