Going beyond files with ItemGroup

If you Google for information on the ItemGroup element of MSBuild, most of the top search results will discuss its use in dealing with files.  The ItemGroup element is far more flexible than this, as I figured out today when making changes to an MSBuild script for creating databases.

My goal was to simplify the targets I was using to create local groups and add users to them.  I started with an example on pages 51-52 of Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build, where the author uses an ItemGroup to create a list of 4 servers.  Each server has custom metadata associated with it.  In his PrintInfo target, he displays the data, overrides an element with new data, and even removes an element.  Because MSBuild supports batching, you can declare a task and attributes once and still execute it multiple times.  Here’s how I leveraged this capability:

  1. I created a target that stored the username of the logged-in user in a property.
  2. I created an ItemGroup.  The metadata for each group element was the name of the local group I wanted to create.
  3. I wrote the Exec commands to execute on each member of the ItemGroup

The ItemGroup looks something like this:

<ItemGroup>
<LocalGroup Include=”Group1″>
<Name>localgroup1</Name>
</LocalGroup>
<LocalGroup Include=”Group2″>
<Name>localgroup2</Name>
</LocalGroup>
<LocalGroup Include=”Group3″>
<Name>localgroup3</Name>
</LocalGroup>
</ItemGroup>

The Exec commands for deleting a local group if it exists, creating a local group, and adding the logged-in user to it, look like this:

<Exec Command=”net localgroup %(LocalGroup.Name) /delete” IgnoreExitCode=”true” />
<Exec Command=”net localgroup %(LocalGroup.Name) /add” IgnoreExitCode=”true” />
<Exec Command=”net localgroup %(LocalGroup.Name) $(LoggedInUser) /add” />

The result is that these commands are executed for each member of the ItemGroup.  This implementation makes a lot easier to add more local groups if necessary, or make other changes to the target.

From enthusiast to user

My friend Sandro read this Slate piece yesterday and wrote this blog entry in part about enthusiasts and users.  I think his concern that today’s computer science students seem to be more users than enthusiasts is very legitimate, since they’re some of the people we’re counting on for the next advances in the field of computing and innovative new products.  The similarity he sees between advances in automobiles and computing is an interesting one.  I agree with him up to a point about commoditization, but I see real benefits to certain things becoming commodities.  He touches only briefly on case mods in the PC space, but commodity hardware (RAM, hard drives, video cards, etc) has made it a lot easier for the technically-inclined to build entire PCs themselves, instead of buying whatever Dell or HP is selling this week.  Commodity hardware and operating systems are what enable a product like TiVo to exist (along with less-capable imitators).  We have commodity hardware to thank for the XBox 360, and commodity operating systems to thank for XBMC.  This doesn’t mean that a ton of people will avail themselves of the option to build their own PC, or their own home theater PC, just that the option is definitely out there for those who want to.

I suspect it has always been the case that the vast majority of people would rather use something cool than build it.  As much as those of us in the U.S. love cars, very few of us will be building our own Rally Fighter anytime soon.  I enjoy photography as a hobby, but I haven’t been in a darkroom to develop my own film in years (nor did I ever spend enough time in one to get really good at the process).  At least with computers, there came a point for me where fiddling around inside the guts of a computer to get something working again got to be too much of a hassle.  This could mean I’m gotten lazy, but I really like it when things just work.  There’s definitely something to be said for having the ability to fix something or hack it to do something beyond its original purpose.  I’ve always admired people like that, and I think they’re responsible for a lot of the great advances we benefit from today.

I think human nature is such that we won’t run out of enthusiasts anytime soon.  As long as there are magazines like MAKE and sites like iFixit, enthusiasts will continue to do things that make users jealous.

Adventures in e-commerce

I’m working on an e-commerce site for the first time in about 10 years.  The site is Trés Spa, a skin care products company in northern California.  Unlike my previous forays into e-commerce, none of the technologies I’m using come from Microsoft.  I’m using the community edition of Magento.  So far, I’ve been able to update the configuration so that USPS shipping options show up in shipping and tax estimates.  I haven’t had to write any code yet, but we’ll see if that changes.  Despite running WordPress for awhile, I’ve done very little with PHP.

More on migrating partially-trusted managed assemblies to .NET 4

Some additional searching on changes to code access security revealed a very helpful article on migrating partially-trusted assemblies.  What I posted yesterday about preserving the previous behavior is found a little over halfway through the article, in the Level1 and Level2 section.

One thing this new article makes clear is that use of SecurityRuleset.Level1 should only be used as a temporary measure until code can be updated to support the new security model.

Upgrading .NET assemblies from .NET 3.5 to .NET 4.0

Code access security is one area that has changed quite significantly between .NET 3.5 and .NET 4.0.  Once an assembly has been upgraded, if it allowed partially-trusted callers under .NET 3.5, it would throw exceptions when called under .NET 4.0.  In order to make such assemblies continue to function after being upgraded, AssemblyInfo.cs needs to change from this:

[assembly: AllowPartiallyTrustedCallers]

to this:

[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityRules(SecurityRuleSet.Level1)]

Once this change has been made, the assembly will work under the same code access security rules that applied prior to .NET 4.0.

Why GDP Matters for Schoolkids

Planet Money, one of many podcasts I listen to in Beltway traffic, had a great episode recently attempting to explain why GDP is important.  The reporter contrasts the resources for a school in Kingston, Jamaica with a socioeconomically similar school in Barbados.  The difference in what a country can do with a per-capita GDP of approximately $15,000/year (Barbados) versus around $5600/year (Jamaica) turns out to be quite staggering.  Hearing about teachers paying for school materials out of their own pockets sounded a lot like what I’ve heard and read in news stories and features about inner-city schools here in the U.S.  One part of the piece that I believe has broader applications to how foreign direct investment (FDI) is used worldwide is when Jamaica’s minister of education (Andrew Holness) explained why the FDI Jamaica has received hasn’t resulted in the expected benefits to the country.  It boiled down to not having enough sufficiently-educated people to staff the projects being built, whether it was bauxite plants or anything else.

A paper by Peter Blair Henry (a Jamaican-born economist) goes into more detail on the comparison between Barbados and Jamaica.  There’s also a podcast of him from last year on the same subject.  I can’t vouch for these latter two links (yet), but the Planet Money episode is worth a listen if you’re at all interested in economics.

When 3rd-party dependencies attack

Lately, I’ve been making significant use of the ExecuteDDL task from the MSBuild Community Tasks project in one of my MSBuild scripts at work.  Today, someone on the development team got the following error when they ran the script:

“Could not load file or assembly ‘Microsoft.SqlServer.ConnectionInfo, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91’

It turned out that the ExecuteDDL task has a dependency on a specific version of Microsoft.SqlServer.ConnectionInfo deployed by the installation of SQL Server 2005 Management Tools.  Without those tools on your machine, and without an automatic redirect in .NET to the latest version of the assembly, the error above results.  The fix for it is to add the following XML to the “assemblyBinding” tag in MSBuild.exe.config (in whichever .NET Framework version you’re using):

<dependentAssembly>
<assemblyIdentity name=”Microsoft.SqlServer.ConnectionInfo” publicKeyToken=”89845dcd8080cc91″ culture=”neutral” />
<bindingRedirect oldVersion=”0.0.0.0-9.9.9.9″ newVersion=”10.0.0.0″ />
</dependentAssembly>

Thanks to Justin Burtch for finding and fixing this bug.  I hope the MSBuild task gets updated to handle this somehow.

Continuous Integration Enters the Cloud

I came across this blog post in Google Reader and thought I’d share it.  The idea of being able to outsource the care and feeding of a continuous integration system to someone else is a very interesting one.  Having implemented and maintained such systems (which I’ve blogged about  in the past), I know it can be a lot of work (though using a product like TeamCity lightens the load considerably compared with CruiseControl.NET).  Stelligent isn’t the first company to come up the idea of CI in the cloud, but they may be the first using all free/open source tools to implement it.

I’ve read Paul Duvall’s book on continuous integration and highly recommend it to anyone who works with CI systems on a regular basis.  If anyone can make a service like this successful, Mr. Duvall can.

Set-ExecutionPolicy RemoteSigned

When you first get started with PowerShell, don’t forget to run ‘Set-ExecutionPolicy RemoteSigned’ from the PowerShell prompt. If you try to run a script without doing that first, expect to see a message like the following:

File <path to file> cannot be loaded because execution of scripts is disabled on this system.  Please see “get-help about_signing” for more details.

The default execution policy for PowerShell is “Restricted” (commands only, not scripts).  The other execution policy options (in decreasing order of strictness) are:

  • AllSigned
  • RemoteSigned
  • Unrestricted

When I first tripped over this, the resource that helped most was a TechNet article.  Later, I found a blog post that was more specific about the execution policies.