0 Comments

So, as I mentioned previously, I built a wall. Well, a garden bed, but there was totally a wall involved.

Honestly, the wall I mentioned in part 01 doesn’t count. It was more concrete Lego than anything else. Just basic staggering of blocks for strength, and the rest is taken care of by the design of the blocks themselves. They just fit together, and they’re designed to interlock and provide strength in the direction that the dirt will be pushing.

Now, its time for the thrilling conclusion. Time to actually build a wall. From bricks. With mortar and everything.

A Strong Foundation

I don’t know if you can see clearly from this photo (as there are some bricks and whatnot in the way), but I needed to smooth out a foundation for the wall before I could do anything else.

The concrete slab that was already present was not a flat surface. It was also broken in 2 places, which would have made laying bricks on top of the existing base awkward and a bit crap.

I’m not sure if this is a normal step for building a brick wall, but I wasn’t comfortable with just jamming a bunch of mortar onto the uneven surface and then laying the bricks on top of that. I wanted to create a flat surface to work on.

I chose to use the same mortar that I was planning to use for the wall itself. Perhaps not the best solution, but it worked okay. I feel like maybe concrete would have been a better idea? I think they have patching concrete for just this purpose.

I used a total of 3 bags of Bastion Mortar from Bunnings (approx. $10/bag), one bag at a time. This was the same brand as the post-mix concrete that I used for the base of the retaining wall.

The instructions on the back of the bag say to add 5.2 litres of water per bag. In a similar case to the concrete though, I found that either this was not enough, or the Queensland heat really messes up those sort of calculations, because adding only the required amount of water did not give me mortar that was easy to work with. Much too dry. Easily solved though, literally just add water (small amounts, mixed thoroughly through each time).

As is always a good way to start when you’re doing some amateur work like this, I watched a few videos on YouTube. The test that I used for whether or not the mortar was any good to work with was “If it sticks to the trowel when you hold it vertically, then its good to go.”. I just kept adding water and mixing until it stuck to the trowel, and that seemed to work out okay.

I didn’t have a mortar board, so I just used the mortar straight out of my wheelbarrow, mixing it every time I needed to grab some more. If you don’t mix each time, the water will separate from the mortar, which you do not want.

I used some smaller pine boards that I had to create a gap between the fence palings and where the edge of the base was going to be. I didn’t want the wall to be flush with the fence because 1.) None of the other back walls of the garden beds were flush with the fence and 2.) I didn’t want the mortar to bond with the fence palings, which would make the fence hard to repair in the future. I tried using the larger 3 metre boards that I used to frame the concrete slab, but it wouldn’t sit at the right height, so I had to use smaller boards.

With the boards in place creating a sort of a frame, I just added mortar and smoothed it out to be in line with the other parts of the current slab.

I left it to cure for a few days, just to be sure. In the same way as the concrete, I made sure to come out every few hours for the first 24 hours to tap the frame so that the concrete didn’t bond with it.

Bricks and Mortar

Now that I had a flat surface to work with, it was time to actually build the wall.

As with every house ever, I had a bunch of bricks leftover from other things. I’d used a lot of them to build test garden beds on the east side of my house, but I still had enough left over to build the wall.

I found that it was a good idea to space the bricks out ahead of time, so that I knew approximately how much gap I should leave between them each time in order to get a nice consistent wall that fit smoothly with the two existing walls. I actually did this before I created the base.

From spacing out the base layer, I knew that I needed at least 1 half brick per row of bricks. I’ve seen people break bricks with the trowel they are using. I have no idea how they do that, whether its more related to the kind of brick they are using or something else, but I had to use a cold chisel to break a brick in half and clean it up.

I don’t have any pictures of the wall as it was being constructed, but it amounted to:

  1. Slap some mortar down where the brick is going to go.
  2. Wipe some mortar on the edge of the brick you are going to lay. It helps to create a bit of a ditch in the centre of the mortar (lengthwise), so that when you lay the brick, it can be tapped down to the right height without needing to push too much mortar out the edges.
  3. Lay the brick, butting the mortared edge up against the brick that’s already there.
  4. Tap the brick until it lines up with the brick next to it. I used a rubber mallet to tap the brick down to the required height, but you can use anything.
  5. Scrape the excess mortar off the sides, making sure to fill any gaps (there shouldn’t be any if you laid the brick properly).
  6. Repeat.

It will take some practice. Luckily my wall is just the back edge of a garden, so it didn’t matter too much if I mucked it up. The only thing I would hurt is my own perfectionist, and that guy could do with being knocked down a few pegs anyway.

I suggest watching some videos as well, I found this one to be quite good. He has a soothing voice.

If you look closely you can see that one of my rows of bricks has a really thick mortar line close to the end. I messed up in the spacing, so I had to fill the bigger than usual gap with mortar. It seems to be okay, but I don’t recommend it.

I ran out of mortar after doing the first two rows of bricks, so I had to come back later with more mortar and add the last 4 bricks (on the left side, meshing in with the existing wall) and fill up all the holes in the top (I didn’t have any caps for the bricks, and you need to fill up the holes so they don’t become perfect places for snails/other annoying things to breed).

Fill ‘er Up

After leaving the mortar to cure for a few days, it was time to fill up the garden bed.

When I originally excavated the area, I took out a few wheelbarrow loads of soil. I think there was 3. I sifted the soil on the way out, so it was good to put back in.

To the soil I added a 40 litre bag of organic compost (Enviroganics Premium Compost from Centenary Landscaping), 3 x 15 kg bags of horse manure and probably 5 kg (all told) of gypsum (to help water retention and to deal with the naturally high level of clay in my soil).

I watered this thoroughly, and then topped it with a mixture of my own compost, Sugar Cane Mulch, Lucerne Mulch and my own mulch (which is just random shredded plant cuttings, palm fronds and so on). This is the same mixture that I use whenever I need to top up the mulch on any of my garden beds (except the vegetable beds, they just get Sugar Cane/Lucerne mix for now, because my fiancé thinks my mulch looks ugly).

After another water to settle everything down I sprinkled a bag of assorted flower/green compost mix seeds over the top, to help the bed settle in and maybe attract some good bugs.

I’ll need to plant something big, green and permanently leafy there eventually (to act as a privacy screen), but I need to make sure the soil is high quality first. I might plant a batch of beans or lucerne or some other nitrogen fixing plant after the flowers/green compost (although, that seed mix did already have lucerne in it, so I might be okay).

Conclusion

I knew the job wasn’t all that large because every time I asked a builder/landscaper about it, they basically said it was too small for them to bother doing. Still, it was a big job for a massive amateur like myself. All in all, it wasn’t as bad as I thought it was going to be though, which was nice.

I’d never laid concrete or built a wall using mortar before, and there is certainly an amount of skill required to do those things properly. I do not yet have that skill, and I doubt I ever will as I cant see many other jobs like this one in the future. You never know though, and I would definitely consider this a good learning experience.

It definitely looks a lot better than it used to, which means that I must have done something right.

I was originally going to have a gfycat animated gif of the change here, but my upload never seems to finish. If if ever works I’ll update this.

Also, here’s an Imgur album of all of the photos (plus a few extra) for this post.

Additional tools/materials used (in addition to those listed in Part 01)

  • More timber planks (just pine, probably treated, it doesn’t really matter)
  • 3 x 20 kg bags of Mortar mix.
  • A bunch of bricks (30ish)
  • 1 x 40 Litre bag of compost
  • 1/2 x 20 kg bag of gypsum
  • 3 x 15 kg bags of horse manure
  • Indeterminate amount of mulch (4 wheelbarrow loads, quite a lot)
  • Trowel

1 Comments

Update: I ran into an issue with the script used in this post to do the signing when using an SHA-256 certificate (i.e. a newer one). You wrote another post describing the issue and solution here.

God I hate certificates.

Everything involving them always seems to be painful. Then you finally get the certificate thing done after hours of blood, sweat and pain, put it behind you, and some period of time later, the certificate expires and it all happens again. Of course, you’ve forgotten how you dealt with it the first time.

I’ve blogged before about the build/publish script I made for a ClickOnce WPF application, but I neglected to mention that there was a certificate involved.

Signing is important when distributing an application through ClickOnce, as without a signed installer, whenever anyone tries to install your application they will get warnings. Warnings like this one.

setup.exe is not commonly downloaded and could harm your computer

For a commercial application, that’s a terrible experience. Nobody will want to install a piece of software when their screen is telling them that “the author of the software is unknown”. And its red! Red bad. Earlier versions of Internet Explorer weren’t quite as hostile, but starting in IE9 (I think) the warning dialog was made significantly stronger. Its hard to even find the button to override the warning and just install the damn thing (Options –> More Options –> Run Anyway, which is a really out of the way).

As far as I can tell, all ClickOnce applications have a setup.exe file. I have no idea if you can customise this, but its essentially just a bootstrapper for the .application file which does some addition checks (like .NET Framework version).

Anyway, the appropriate way to deal with the above issue is by signing the ClickOnce manifests.

You need to use an Authenticode Code Signing Certificate, from a trusted Certificate Authority. These can range in price from $100 US to $500+ US. Honestly, I don’t understand the difference. For this project, we picked up one from Thawte for reasons I can no longer remember.

There’s slightly more to the whole signing process than just having the appropriate Certificate and Signing the installer. Even with a fully signed installer, Internet Explorer (via SmartScreen) will still give a warning to your users when they try to install, saying that “this application is not commonly downloaded”. The only way around this is to build up reputation with SmartScreen, and the only way to do that is slowly, over time, as more and more people download your installer. The kicker here is that without a certificate the reputation is tied to the specific installer, so if you ever make a new installer (like for a version update) all that built up reputation will go away. If you signed it however, the reputation accrues on the Certificate instead.

Its all very convoluted.

Enough time has passed between now and when I bought and setup the certificate for me to have completely forgotten how I went about it. I remember it being an extremely painful process. I vaguely recall having to generate a CSR (Certificate Signing Request), but I did it from Windows 7 first accidentally, and you can’t easily get the certificate out if you do that, so I had to redo the whole process on Windows Server 2012 R2. Thawte took ages to process the order as well, getting stuck on parts of the certification process a number of times.

Once I exported the certificate (securing the private key with a password) it was easy to incorporate it into the actual publish process though. Straightforward configuration option inside the Project properties, under Signing. The warning went from red (bad) to orange (okayish). This actually gives the end-user a Run button, instead of strongly recommending to just not run this thing. We also started gaining reputation against our Certificate, so that one day it would eventually be green (yay!).

Do you want to run or save setup.exe from

Last week, someone tried to install the application on Windows 8, and it all went to hell again.

I incorrectly assumed that once installed, the application would be trusted, which was true in Windows 7. This is definitely not the case in Windows 8.

Because the actual executable was not signed, the user got to see the following wonderful screen immediately after successfully installing the application (when it tries to automatically start).

windows protected your PC

Its the same sort of thing as what happens when you run the installer, except it takes over the whole screen to try and get the message across. The Run Anyway command is not quite as hidden (click on More Info) but still not immediately apparent.

The root cause of the problem was obvious (I just hadn’t signed the executable), but fixing it took me at least a day of effort, which is a day of my life I will never get back. That I had to spend in Certificate land. Again.

First Stab

At first I thought I would just be able to get away with signing the assembly. I mean, that option is directly below the configuration option for signing the ClickOnce manifests, so they must be related, right?

I still don’t know, because I spent the next 4 hours attempting to use my current Authenticode Code Signing Certificate as the strong name key file for signing the assembly.

I got an extremely useful error message.

Error during Import of the Keyset: Object already exists.

After a bit of digging it turns out that if you did not use KeySpec=2 (AT_SIGNATURE) during enrollment (i.e. when generating the CSR) you can’t use the resulting certificate for strong naming inside Visual Studio. I tried a number of things, including re-exporting, deleting and then importing the Certificate trying to force AT_SIGNATURE to be on, but I did not have any luck at all. Thawte support was helpful, but in the end unable to do anything about it.

Second Stab

Okay, what about signing the actual executable? Surely I can use my Authenticode Code Signing Certificate to sign the damn executable.

You can sign an executable (not just executables, other stuff too) using the CodeSign tool, which is included in one of the Windows SDKs. I stole mine from “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\bin”. The nice thing is that its an (entirely?) standalone application, so you can include it in your repository in the tools directory so that builds/publish

Of course, because I’m publishing the application through ClickOnce its not just as simple as “sign the executable”. ClickOnce uses the hash of files included in the install in the generation of its .manifest file, so if you sign the executable after ClickOnce has published to a local directory (before pushing it to the remote location, like I was doing) it changes the hash of the file and the .manifest is no longer valid.

With my newfound Powershell skills (and some help from this awesome StackOverflow post), I wrote the following script.

param
(
    $certificatesDirectory,
    $workingDirectory,
    $certPassword
)

if ([string]::IsNullOrEmpty($certificatesDirectory))
{
    write-error "The supplied certificates directory is empty. Terminating."
    exit 1
}

if ([string]::IsNullOrEmpty($workingDirectory))
{
    write-error "The supplied working directory is empty. Terminating."
    exit 1
}

if ([string]::IsNullOrEmpty($certPassword))
{
    write-error "The supplied certificate password is empty. Terminating."
    exit 1
}

write-output "The root directory of all files to be deployed is [$workingDirectory]."

$appFilesDirectoryPath = Convert-Path "$workingDirectory\Application Files\[PUBLISH DIRECTORY ROOT NAME]_*\"

write-output "The application manifest and all other application files are located in [$appFilesDirectoryPath]."

if ([string]::IsNullOrEmpty($appFilesDirectoryPath))
{
    write-error "Application Files directory is empty. Terminating."
    exit 1
}

#Need to resign the application manifest, but before we do we need to rename all the files back to their original names (remove .deploy)
Get-ChildItem "$appFilesDirectoryPath\*.deploy" -Recurse | Rename-Item -NewName { $_.Name -replace '\.deploy','' }

$certFilePath = "$certificatesDirectory\[CERTIFICATE FILE NAME]"

write-output "All code signing will be accomplished using the certificate at [$certFilePath]."

$appManifestPath = "$appFilesDirectoryPath\[MANIFEST FILE NAME]"
$appPath = "$workingDirectory\[APPLICATION FILE NAME]"
$timestampServerUrl = "http://timestamp.globalsign.com/scripts/timstamp.dll"

& tools\signtool.exe sign /f "$certFilePath" /p "$certPassword" -t $timestampServerUrl "$appFilesDirectoryPath\[EXECUTABLE FILE NAME]"
if($LASTEXITCODE -ne 0)
{
    write-error "Signing Failure"
    exit 1
}

# mage -update sets the publisher to the application name (overwriting any previous setting)
# We could hardcode it here, but its more robust if we get it from the manifest before we
# mess with it.
[xml] $xml = Get-Content $appPath
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("asmv1", "urn:schemas-microsoft-com:asm.v1")
$ns.AddNamespace("asmv2", "urn:schemas-microsoft-com:asm.v2")
$publisher = $xml.SelectSingleNode('//asmv1:assembly/asmv1:description/@asmv2:publisher', $ns).Value
write-host "Publisher extracted from current .application file is [$publisher]."

# It would be nice to check the results from mage.exe for errors, but it doesn't seem to return error codes :(
& tools\mage.exe -update $appManifestPath -certFile "$certFilePath" -password "$certPassword"
& tools\mage.exe -update $appPath -certFile "$certFilePath" -password "$certPassword" -appManifest "$appManifestPath" -pub $publisher -ti $timestampServerUrl

#Rename files back to the .deploy extension, skipping the files that shouldn't be renamed
Get-ChildItem -Path "$appFilesDirectoryPath"  -Recurse | Where-Object {!$_.PSIsContainer -and $_.Name -notlike "*.manifest"} | Rename-Item -NewName {$_.Name + ".deploy"}

Its not the most fantastic thing I’ve ever written, but it gets the job done. Note that the password for the certificate is supplied to the script as a parameter (don’t include passwords in scripts, that’s just stupid). Also note that I’ve replaced some paths/names with tokens in all caps (like [PUBLISH DIRECTORY ROOT NAME]) to protect the innocent.

The meat of the script does the following:

  • Locates the publish directory (which will have a name like [PROJECT NAME]_[VERSION]).
  • Removes all of the .deploy suffixes from the files in the publish directory. ClickOnce appends .deploy to all files that are going to be deployed. I do not actually know why.
  • Signs the executable.
  • Extracts the current publisher from the manifest.
  • Updates the .manifest file.
  • Updates the .application file.
  • Restores the previously removed .deploy suffix.

You may be curious as to why the publisher is extracted from the .manifest file and then re-supplied. This is because if you update a .manifest file and you don’t specify a publisher, it overwrites whatever publisher was there before with the application name. Obviously, this is bad.

Anyway, the signing script is called after a build/publish but before the copy to the remote location in the publish script for the application.

Conclusion

After signing the executable and ClickOnce manifest, Windows 8 no longer complains about the application, and the installation process is much more pleasant. Still not green, but getting closer.

I really do hate every time I have to interact with a certificate though. Its always complicated, complex and confusing and leaves me frustrated and annoyed at the whole thing. Every time I learn just enough to get through the problem, but I never feel like I understand the intricacies enough to really be able to do this sort of thing with confidence.

Its one of those times in software development where I feel like the whole process is too complicated, even for a developer. It doesn’t help that not only is the technical process of using a certificate complicated, but even buying one is terrible, with arbitrary price differences (why are they different?) and terrible processes that you have to go through to even get a certificate.

At least this time I have a blog, and I’ve written this down so I can find it when it all happens again and I’ve purged all the bad memories from my head.

0 Comments

Continuing on with my saga of “I’m not very handy, but I don’t want to pay someone to do these things”, I built a wall.

Well, two walls really.

Okay, its a garden bed, but there were bricks involved, mortar, concrete, all sorts of wall-building shenanigans, so I’m counting it as a wall.

My back yard features a garden bed that follows the north and north-east fencelines. Its quite nice, it has some greenery in it that gives the back yard some privacy. Except for right in the middle.

I assume at some point it was supposed to be a feature? It has a palm and a paw-paw tree, neither of which look fantastic, and an “edge” made of rocks.

Pretty crap right? Also, inconsistent, which bugs me more than I would like to admit.

We’ve wanted to fix this little area for a while now, so I thought I would take the opportunity (while I wait to start my new job) to do just that.

In order to avoid making this blog post too long, I’m going to break this mini-project into two posts.

This post will focus on the destruction of the current area and the construction of the inner-wall (i.e. the edge closest to the lawn) while the next post will focus on the outer-wall construction and any miscellaneous sundries.

Lord of Destruction

Sometimes you have to destroy before you can create, and while I regret the loss of a perfectly good palm, it had to come out if I was going to do this. I do not regret the loss of the paw-paw, because 1.) I never got any fruit off it because the bats just ate it all, and 2.) The fruit tastes terrible anyway.

Anyway, the destruction, from easiest to hardest.

The edging. Just modular retaining wall blocks, so easy to move. Pickup, move. Simple. I stashed them inside with the rest of the spare blocks I had (from tearing apart another similar bed on the east side of the house where my vegie gardens are now). I’ll need those blocks later to build the wall.

The rocks at the front, also easy. Tore them out and stashed them on the west side of my house to build a retaining wall.

The paw-paw tree (the one on the right in the picture above) was also surprisingly easy. A couple of good rocks from side to side and it came right out. Whoever planted it didn’t really put it in a good place. It was jammed right into a corner, so the roots had nowhere to go. Also, it was rotten (which I did not know until the top part of the tree almost smacked me in the head).

The palm. Now this was hard. While it didn’t exactly have a massive taproot or anything, it still had a lot of little roots spread throughout the area it was in. One big taproot would probably have been easier actually, because I had to dig a trench all the way around the base of the palm before I could rock it even the smallest amount. A significant amount of effort later, it too fell. I cut it up and stashed the pieces down the side of my house to dry so I could break them apart later for mulch. I did the same with the remains of the paw-paw tree. Never waste any organic matter, it all breaks down in the end.

Now for the hardest bit, the concrete. Underneath the left and right edging of the existing garden beds were concrete slabs. About 15cm thick. These slabs were what the retaining wall blocks were sitting on. You can see them on the left and right in the picture below.

Unsurprisingly concrete is hard to break when you do not have a concrete saw. I do not have a concrete saw.

After about 2 hours of smash-lever-poke-smash-etc with a pickaxe and a crowbar thing (it wasn’t so much a crowbar as it was just a big steel stick with a pointy end) the concrete slabs were broken and removed.

The last bit of cleanup involved excavating some of the soil and moving it somewhere else while I worked on the area. Lots of stones and debris, so I sifted it before dumping it. I’ve got a big pile of knuckle to fist sized rocks from this and all the other times I’ve sifted my soil. I’d love to hire a rock-crusher to turn them into dust and incorporate it back into the garden, but I don’t think you can. Ah well, maybe I’ll smash them myself.

The dogs are curious about the new development.

Time to lay the foundation for the inner-wall.

Is that Concrete in your Pocket or are you Happy to See Me?

I have never laid concrete before in my life. I do not particularly want to lay concrete again.

Anyway, I did some rough calculations and in order to lay the slab at the front for the retaining wall blocks to sit on, I would need approximately 0.01 m3 of concrete (2.6 m, x 0.3m x 0.15 m), which ends up being about 12 bags of the stuff. I went with post-mix concrete from Bunnings for about $6 for a 20 kg bag.

I needed a frame too, to hold it in place while it cured.

At first I considered using some scrap timber that I had laying around (which you can see on top of the concrete bags in the photo above), but I very quickly rejected this idea when I went to construct the frame, as it would have taken too much effort to attach the planks together into the required shape. Instead I just purchased two 3 m pine planks and some wooden stakes. This actually turned out to be a much better idea, because I could brace the planks on the existing concrete slabs and get a nice smooth integration.

Now, in order to make the concrete, I first followed the instructions on the bags exactly. 4.2 L of water per bag of concrete. I could fit two bags of concrete into my wheelbarrow, so 8.2 L of water. Dutifully measured via my watering can and added. Mixing that stuff by hand is rough work too, it’s not easy to move around and it needs a lot of moving around before its ready to go. I treated it similarly to making pasta or bread dough. Well in the centre, add all the liquid and slowly incorporate the dry stuff.

The first batch of concrete seemed a little..dry? I mean, it still went into the frame okay, but it just didn’t look like the same sort of consistency that I had seen concreters work with in the past.

I over-compensated for the second batch.

But finally found a good consistency for the third and fourth batches.

Look at that second batch drip. Terrible.

In that last picture I’ve already finished the concrete a little (with the edger on the lawn side, and smoothing it out a little on top). Generally you need to wait an hour or two after laying the concrete before you can finish it, but in the Queensland heat, it was ready in less than an hour.

Now we play the waiting game, as the concrete needs to sit and cure for at least 24 hours before I can remove the frame and start putting stuff on it. I hope it doesn’t rain.

Mr President, Build up this Wall

Ha ha ha ha rain. This is Queensland, Australia. What’s rain?

Just to be sure, I left the concrete for two days. However, I did come out every couple of hours after I laid it to tap the frame with a rubber mallet. This helps to make sure that the concrete doesn’t bond to the timber frame, which can make it a pain to remove.

The frame came off really easy once I knocked the stakes out of the ground.

Lets build a wall! Its just like Lego, except there’s no danger of stepping on a piece and suffering the most unimaginable pain…imaginable?

Honestly, this part went smoothly, without incident. The only tricksy bit was that I needed to move an entire row of blocks a couple of times in order to get a nice tight fit in the middle. That and I ran out of blocks, so I had to steal some from a different part of the yard. If I can’t find any more of these blocks I’ll probably have to turn the spot I stole the blocks from into a “feature” wall or something.

Mmmmm, looking good. I even used pre-loved blocks, so the only hint it wasn’t always there is the really new looking concrete and the missing grass at the front. Sneaky.

Heres an imgur album of all of the photos together, for your viewing pleasure.

Summary of Tools and Materials (so far)

  • Axe
  • Saw
  • Steel rod thing (crowbar?)
  • Hammer
  • Chisel
  • Rubber Mallet
  • Gloves (important! concrete does a number on your skin)
  • Timber planks
  • Timber stakes
  • 8 x 20 kg bags of post-mix Concrete (I bought 12, but only used 8. I think I ended up making the slab thinner than I planned)
  • Water (duh)

Next Time

Literally, bricks and mortar.

0 Comments

I know just enough of the windows scripting language (i.e. batch files) to get by. I’ve written a few scripts using it (at least one of which I’ve already blogged about), but I assume there is a world of deeper understanding and expertise there that I just haven’t fathomed yet. I’m sure its super powerful, but it just feels so…archaic.

Typically what happens is that I will find myself with the need to automate something, and two options will come to mind:

  1. I could write a batch file. This is always a struggle, because I write C# code all day, and going back to the limited functionality of the windows scripting language is painful. I know that if I want to do something past a certain point of complexity, I’ll need to combine this approach with something else.
  2. I could write a C# application of some sort (probably console) that does the automation. C# is where most of my skills lie, but it seems like I’m overcomplicating a situation when I build an entire C# console application. Additionally, if I’m automating something, I want it to be as simple and readable as possible for the next person (which may be me in 3 months) and encapsulating a bunch of automation logic into a C# application is not immediately discoverable.

I usually go with option 1 (batch file), which to me, is the lesser of two evils.

Enter Powershell

I’ve always secretly known that there are more than 2 options, probably many more.

At the very least there is a 3rd option:

  1. Use Powershell. Its just like a batch file, except completely different. You can leverage the .NET framework, and you get a lot more useful built in commands.

For me, the downside of using Powershell has always been the learning curve.

Every time I go to solve a problem that Powershell might be useful for, I can never justify spending the time to learn Powershell, even just the minimum needed to get the job done.

I finally got past that particular mental block recently when I wanted to write an automated build script that did the following:

  1. Update a version.
  2. Commit changes to git.
  3. Build a C# library project.
  4. Package the library into a NuGet package.
  5. Track the package in git for later retrieval.

There’s a lot of complexity hidden in those 5 statements, enough such that I knew I wouldn’t be able to accomplish it using just the vanilla windows scripting language. I resolved that this was definitelynot something that should be hidden inside the source code of an application, so it was time to finally go nuclear and learn how to do the Powershell.

Getting Started

The last time I tried to use Powershell was a…while ago. Long enough such that it wasn’t guaranteed that a particular computer would have Powershell installed on it. That’s pretty much not true anymore, so you can just run the “powershell” command from the command line to enter the Powershell repl. Typing “exit” leaves Powershell and returns you back to your command prompt.

Using Powershell on the command line is all well and good for exploration, but how can I use it for scripting?

powershell -Executionpolicy remotesigned -File [FileName]

The –Executionpolicy flag makes it so that you can actually run the script file. By default Powershell has the Restricted policy set, meaning scripts will not run.

Anyway, seems straightforward enough, so without further ado, I’ll show you to the finished Powershell script to accomplish the above, and then go through it in more detail.

The Script

param ( [switch]$release ) $gitTest = git if($gitTest -match "'git' is not recognized as an internal or external command") { write-error "Cannot find Git in your path. You must have Git in your path for this package script to work." exit } # Check for dirty git index (i.e. uncommitted, unignored changes). $gitStatus = git status --porcelain if($gitStatus.Length -ne 0) { write-error "There are uncommitted changes in the working directory. Deal with them before you package, or the tag that's made in git as a part of a package will be incorrect." exit } $currentUtcDateTime = (get-date).ToUniversalTime() $assemblyInfoFilePath = "[PROJECT PATH]\Properties\AssemblyInfo.cs" $assemblyVersionRegex = "(\[assembly: AssemblyVersion\()(`")(.*)(`"\))" $assemblyInformationalVersionRegex = "(\[assembly: AssemblyInformationalVersion\()(`")(.*)(`"\))" $existingVersion = (select-string -Path $assemblyInfoFilePath -Pattern $assemblyVersionRegex).Matches[0].Groups[3] $existingVersion = new-object System.Version($existingVersion) "Current version is [" + $existingVersion + "]." $major = $existingVersion.Major $minor = $existingVersion.Minor $build = $currentUtcDateTime.ToString("yy") + $currentUtcDateTime.DayOfYear $revision = [int](([int]$currentUtcDateTime.Subtract($currentUtcDateTime.Date).TotalSeconds) / 2) $newVersion = [System.String]::Format("{0}.{1}.{2}.{3}", $major, $minor, $build, $revision) "New version is [" + $newVersion + "]." "Replacing AssemblyVersion in [" + $assemblyInfoFilePath + "] with new version." $replacement = '$1"' + $newVersion + "`$4" (get-content $assemblyInfoFilePath) | foreach-object {$_ -replace $assemblyVersionRegex, $replacement} | set-content $assemblyInfoFilePath if ($release.IsPresent) { $newInformationalVersion = $newVersion } else { write-host "Building prerelease version." $newInformationalVersion = [System.String]::Format("{0}.{1}.{2}.{3}-pre", $major, $minor, $build, $revision) } "Replacing AssemblyInformationalVersion in [" + $assemblyInfoFilePath + "] with new version." $informationalReplacement = '$1"' + $newInformationalVersion + "`$4" (get-content $assemblyInfoFilePath) | foreach-object {$_ -replace $assemblyInformationalVersionRegex, $informationalReplacement} | set-content $assemblyInfoFilePath "Committing changes to [" + $assemblyInfoFilePath + "]." git add $assemblyInfoFilePath git commit -m "SCRIPT: Updated version for release package." $msbuild = 'C:\Program Files (x86)\MSBuild\12.0\bin\msbuild.exe' $solutionFile = "[SOLUTION FILENAME]" .\tools\nuget.exe restore $solutionFile & $msbuild $solutionFile /t:rebuild /p:Configuration=Release if($LASTEXITCODE -ne 0) { write-host "Build FAILURE" -ForegroundColor Red exit } .\tools\nuget.exe pack [PATH TO PROJECT FILE] -Prop Configuration=Release -Symbols write-host "Creating git tag for package." git tag -a $newInformationalVersion -m "SCRIPT: NuGet Package Created."

[Wall of text] crits [reader] for [astronomical amount of damage].

To prevent people from having to remember to run Powershell with the correct arguments, I also created a small batch file that you can just run by itself to execute the script.

@ECHO OFF

powershell -Executionpolicy remotesigned -File _Package.ps1 %*

As you can see, the batch script is straightforward. All it does is call the Powershell script, passing in any arguments that were passed to the batch file (that’s the %* at the end of the line).

Usage is:

package // To build a prerelease, mid-development package.

package –release // To build a release package, intended to be uploaded to NuGet.org.

Parameters

The first statement at the top defines parameters to the script. In this case, there is only one parameter, and it defines whether or not the script should be run in release mode.

I wasn’t comfortable with automatically making every single package built using the script a release build, because it meant that if I automated the upload to NuGet.org at some later date, I wouldn’t be able to create a bunch of different builds during development without potentially impacting on people actually using the library (they would see new versions available and might update, which would leave me having to support every single package I made, even the ones I was doing mid-development). That’s less than ideal.

The release flag determines whether or not the AssemblyInformationalVersion has –pre appended to the end of the version string. NuGet uses the AssemblyInformationalVersion in order to define whether or not the package is a prerelease build, which isolates it from the normal stream of packages.

Checks

Because the script is dependent on a couple of external tools that could not be easily included in the repository (git in particular, but also MSBuild) I wanted to make sure that it failed fast if those tools were not present.

I’ve only included a check for git because I assume that the person running the script has Visual Studio 2013 installed, whereas git needs to be in the current path in order for the script to do what it needs to do.

The other check that the script does is check to see whether or not there are any uncommitted changes.

I do this because one of the main purposes of this build script is to build a library and then mark the source control system so that the source code for that specific version can be retrieved easily. Without this check, someone could use the script with uncommitted local changes and the resulting tag would not actually represent the contents of the package. Super dangerous!

Versioning

In this particular case, versioning is (yet again) a huge chunk of the script, as it is intended to build a library for distribution.

The built in automatic versioning for .NET is actually pretty good. The problem is, I have never found a way to use that version easily from a build script and the version is never directly stated in the AssemblyInfo file, so you can’t see the version at a glance just by reading the code. I need more control than that.

The algorithm that the .NET framework uses is (partially) explained in the documentation for AssemblyVersion.

To summarise:

  1. The version is of the form [MAJOR].[MINOR].[BUILD].[REVISION].
  2. You can substitute a * for either (or both of) BUILD and REVISION.
  3. BUILD is automatically set to the number of days since 1 January 2000.
  4. REVISION is automatically set to the number of seconds since midnight / 2.

The algorithm I implemented in the script is a slight modification of that, where BUILD is instead set to YYDDD.

Anyway, Powershell makes the whole process of creating this new version much much easier than it would be a normal batch file, primarily because of the ability to use the types and functions in the .NET framework. Last time I tried to give myself more control over versioning I had to write a custom MSBuild task.

The script grabs the version currently in the AssemblyVersion attribute of the specified AssemblyInfo file using the select-string cmdlet. It extracts the MAJOR and MINOR numbers from the existing version (using the .NET Version class) and then creates a string containing the new version.

Finally, it uses a brute force replacement approach to jam the new version back into the AssemblyVersion attribute, using the same regular expression. I’ll be brutally honest, I don’t understand the intricacies of the way in which it does the replacement, just that it reads all of the lines from the file, modifies any that match the regular expression, then writes them all back, effectively overwriting the entire file. I wouldn’t recommend this approach for any serious replacement, but AssemblyInfo is a very small file, so it doesn’t matter all that much here.

Some gotchas here. Initially I broke the regular expression into 3 groups. Left of the version, the version and right of the version. However, when it came time to do the replace, I could not create a replacement string using the first capture group + the new version because the resulting string came out like this “$11.2.14309.2306”. When Powershell/.NET tried to substitute the capture groups in, it tried to substitute the $11 group, which didn’t exist. Simply adding whitespace would have broken the version in the file, so I had to break the regular expression into 3 groups, one of which is just the single double quotes to the left of the version. When it comes time to do the replacement, I just manually insert that quote and that worked. A bit nastier than I would like, but ah well.

The version update is then duplicated for the AssemblyInformationalVersion, with the previously mentioned release/prerelease changes.

Source Control

A simple git add and commit to ensure that the altered AssemblyInfo file is in source control, ready to be tagged after the build is complete. I prepended the commit message with “SCRIPT:” so that its easy to tell which commits were done automatically when looking at the git log output.

Build

Nothing fancy, just a normal MSBuild execution, preceded by a NuGet package restore.

I struggled with calling MSBuild correctly from the script for quite a while. For some reason Powershell just would not let me call it with the appropriate parameters. Eventually I stumbled onto this solution. & is simply the call operator.

The script checks that there weren’t any errors during the build, because there would be no point in going any further if there was. The $LASTEXITCODE variable is a handy little variable that tracks the last exit code from a call.

Packaging

Simple NuGet package command. I use –Symbols because I prefer NuGet packages that include source code, so that they are easier to debug. This is especially useful for a library.

Source Control (again)

If we got this far, we need to create a record that the package was created. A simple git tag showing the same version as the AssemblyInformationalVersion is sufficient.

Summary

As you can clearly see, the script is not perfect. Honestly, I’m not even sure if its good. At the very least it gets the job done. I’m sure as I continue to use it for its intended purpose I will come up with ways to improve it and make it clearer and easier to understand.

Regardless of that, Powershell is amazing! The last time I tried to solve this problem I wrote a custom MSBuild task to get the versioning done. That was a lot more effort than the versioning in this script, and much harder to maintain moving forward. The task was better structured though, so that’s definitely an area where this script could use some improvement. Maybe I can extract the versioning code out into a function? Another file maybe? I should almost certainly run the tests before packaging as well, no point in making a package where the library has errors that could have been picked up. Who knows, I’m sure I’ll come up with something.

You may also ask why I went to all this trouble when I should be using a build server of some description.

I agree, I should be using a build server. For the project that this build script was written for I don’t really have the time or resources to put one into place…yet.

0 Comments

I have two awesomely annoying (annoyingly awesome?) dogs.

Unsurprisingly, they create a lot of poop. Droppings. Leavings. Faeces. Crap. You know what I’m talking about.

I like to think I’m an environmentally conscious kind of guy. My fiancée thinks I am an insane hippy, so I must be doing something right. Anyway, I didn’t just want to pick it all up, lump it in a plastic bag and then make it someone else’s problem. That doesn’t seem fair. They are my dogs, it should be my problem.

Surely I can incorporate its disposal into my garden. Maybe it will even help?

I’ve spoken a little bit before about how cruddy my soil is. Its mostly stones, clay, dust and pain. Everything I do at this stage of my garden pretty much comes straight back to “does this make the soil better”. My garden beds are isolated from the surrounding and underlying soil (raised beds) and I had soil brought in for my turf before it was laid. I still have a lot of area that is dreadfully unhealthy in terms of soil though, so I have plenty of places where I can do experiments to see what improves my soil.

Compost

At first I thought that it would be a good idea to just put the poop in my active compost bin, with the rest of the vegetable scraps and occasional forkful of carbon.

I have two compost bins right now. Typically one is active (I’m putting scraps and mulch into it) while the other is still breaking down. That way I can use the compost from one, while still adding new stuff to the other. Its a nice simple rotation.

That worked okay, but I wasn’t really comfortable with it. I’m sure it didn’t necessarily hurt the resulting compost, but I wasn’t sure if the bins would get to the required temperature to break down the poop properly. I tried burying the poop directly in the middle of the material in the bin (where it should be hottest) but I still didn’t feel comfortable. Even though my dogs are healthy, I was worried about pathogens. That compost is intended to be used directly on my vegetable beds (among other places). It might even be used to make compost tea (which will be applied to my vegetable beds, and other places).

Perhaps my fears are unfounded, but at the very least, adding dog poop into the mix of the compost is also complicating anything that I’m learning about compost. Not worth the trade off.

So, not in the compost.

Burial

I’ve got an entire side of my yard that is just terrible.

Here, look for yourself.

To summarise:

  • Its really rocky and dusty.
  • Its constantly hotter than anywhere else in the yard, due to a combination of the area (two close brick walls, one heats up in the morning, the other in the afternoon) and the air conditioning units (which vent their heat directly into the area when run on hot days).
  • Its on a slope, so any water just runs straight off it, eroding any good topsoil (which, come to think of it, is probably how it got so bad in the first place).

So, I need to regenerate the area, and the first place you start with regeneration, is the soil. Its a gradual process, but I don’t need to hurry, because while I have plans for that side of the house, I don’t need it right now. Slow and steady, soil first.

So, lets bury the poop there and let the worms and other bugs and stuff take care of it. Its out of the way, because I very rarely go down that side of the house. There’s nothing there, so I don’t need to worry about pathogens either.

Each month I dig a hole, and then use that hole to dispose of the dog poop. Typically we pick it up once or twice a week. Then when the next month rolls around, I dig a new hole, use the soil to cover up the old hole, cover the area with mulch (nothing fancy, just whatever I’ve got) and water it heavily.

The first hole didn’t really go that well…

Essentially I unintentionally created a block of poop. It rained, the poop got all liquid, then it got really hot and dry, and it kind of set into a solid block. Very unpleasant, almost impenetrable to worms and beetles and just generally bad. I had to break it up with a spade and then throw some compost and mulch on it to prevent it from happening again.

I make sure to add some compost and mulch to each bucket full of poop that I dispose of now, and its going much better. The mulch keeps the poop from setting into a block and the compost adds additional micro-organisms to help break it down.

To mitigate the slope, at first I just had a pile of mulch, and I would dig holes through the mulch into the soil. While the mulch helped keep some water in the soil (fighting evaporation), the slope worked against me, as excess water would just run away. This led to the soil staying much dryer than I would like. It didn’t seem to negatively affect the breakdown of the poop, but it wasn’t good for the long term regeneration of the area.

Terraces

I decided that I needed to terrace the area, so that runoff wouldn’t be such a big problem.

I used some large stones I had lying around to create a small, low wall. This allowed me to fill up the area behind the wall with mulch and soil (mostly what was there already in the pile) and level it off. This lets the water be absorbed and soak into the soil, which keeps everything much more moist.

Conclusion

I’ve rotated the holes quite a few times since I started disposing of the poop like this, and when it comes time to dig back in the same spot as before, I’ve yet to see any trace of the old poop. The soil is consistently getting better too, as a result of the increased organism activity and the addition of the compost and mulch. Its so much better, that recently I’ve had a few self-sown pumpkins, tomatoes, marigolds and capsicums come up. I know those particular plants aren’t much of an achievement, but they seem healthy enough, so I must be doing something right.

West side of my house, showing retaining wall, current poop disposal area, pumpkin vines and tomato plant.

Now, I wonder if I can make human waste my responsibility as well…