Working from home and staying healthy

For about 8 years, I’ve been primarily working from home. Over the years I made the transition from sitting 14 hours a day to being active while working. With the COVID-19 situation, more and more people are now forced to work from home. Whenever I mention the setup I have at home, people become interested and ask me all about the hardware I purchased over the years.

My office setup, pardon the cable mess…

In the beginning…

…there was a young man, super eager to be a great developer. I worked 12 hours a day and enjoyed *loved* it. Besides the consultancy day jobs I had, I was working at least 4 hours a day on open source technology such as Catel. I didn’t have kids back then and I still had enough time to spend with my wife on fun stuff. Back then, I was convinced that it was important to use great hardware because I was aware that I was sitting most part of the day. This resulted in spending a lot of money on monitors, a desk and, at that time most importantly, a great chair (more on that later).

Mentality change

I noticed something changed after I became 30 years old. Sitting all day on a chair was taking its toll and I got less and less energy. Something had to change, but how? I need to be at a computer all day since that’s the primary tool I use for software development.

Starting to stand a few hours a day

After some investigation and asking around, a friend recommended me a sit-stand-desk. After buying one, I changed from sitting all day to standing about half of the day. This resulted in the following benefits:

  • No more sitting all day
  • It’s actually easier to get a cup of coffee / do something while standing, or look something up real quick on your computer
Photo by Michelle Sharp on Unsplash

Becoming active while working

While I thought the sit-stand-desk was great, I was becoming frustrating to adjust the desk several times a day (even when it has a motor). I also noticed my body was storing more food reserves than I was used to / wanted. But I have a (physically) inactive job, right? This got me thinking: what if I could get a workout device (home trainer), saw off the steer and would use that at the standing desk. After some searching, it became clear there were other clever people that already invented such a device: the Deskbike (more on this later). Whenever I feel the urge to sit, I grab the Deskbike and can keep the desk in the same position. I have a (small) workout with the Deskbike while working. After 30 – 45 minutes, my (bike)legs are becoming tired and I go back into the stand position. This new way of working transformed my sit-stand-desk into a stand-desk.

Photo by Mag Pole on Unsplash

Working out while working

This standing and biking got me really active. It actually motivated me to go a bit further. I wanted to become stronger: my kids are becoming more heavy while they grow, and I want to be able to throw them in the air as long as possible. I decided to buy some weights: a dumbbell tower which saves a lot of space, but still allows a good range of dumbbells pairs from 1 – 10 kg. There are several moments a day where I have a few minutes to spare (e.g. when compiling a large solution, waiting for tests to complete, or …). Instead of waiting, I decided to pick up a few weights and start doing (simple) excercises while waiting for the task to be completed. The great advantage of the stand-desk is that it’s super easy to grab some weights, excersize and get back to work (no need to get up and sit back down).

Photo by Gene Jeter on Unsplash

With the COVID-19 situation, it was no longer possible for me to get my weekly workout at the gym. I didn’t want to stop training and gain weight either during this period. After some searching, I came across HASfit. These people made (and still make) great, free on-line videos for workouts (with or without dumbbells). The advantage is that most of these workouts are short and only take between 10 and 20 minutes. This is a great way to end a day of work. This is the time most people are sitting in the car driving back home, and I decided to use that same time to do a workout instead. I can highly recommend watching these videos and stay fit while you can’t go to the gym.

Hardware setup

Let’s jump into the hardware setup that I’ve gathered over the year to stay fit and healthy while working on a physically inactive job.

Keyboard

I’ve been a big fan of ergonomic keyboards from they day I started software development. I develop RSI fairly quick whenever I type on a “regular” keyboard, so this is on the top of my list. Even when I have to go to a customer with a laptop, I take one of these keyboards with me. Over the years I’ve tested and used lots of keyboards, but the ones I love the most are my GoldTouch keyboards. The main reasons I purchased the Go!2 from GoldTouch are:

1. Less noise (I used to have one of their regular ones, but it was quite noisy)

2. Less travel (the keys are flat, giving me the feeling my fingers need to travel less to hit a key)

One note on this keyboard though: I purchased both the wired and wireless one, but the wireless one is very laggy. If you decided to purchase this keyboard, make sure to purchase the wired one.

Desk

A great motorized sit-stand-desk can be bought at Ikea. Ikea has both motorized and manual sit-stand-desks, but I highly recommend using a motorized one since you will have to change heights multiple times a day. If you differentiate between sitting and standing 4 times a day, you will need to change heights 8 times a day. This is very frustrating having to do this by hand. The one I use is a BEKANT.

Deskbike

The Deskbike is a great way to turn your sit-stand-desk into a stand-desk. No more changing of heights: whenever you feel the urge to sit down, grab your Deskbike and transform the time you sit into an active “workout”. With most of the gadgets, whenever it loses the “new” factor, people tend to use them less and less. After more than a year of active usage, I am still using it multiple times a day, so I highly recommend it (and I think it’s not that expensive).

Monitor

My monitor is fairly new, but combined with Windows PowerToys I am loving the experience. The monitor is a SAMSUNG 49″ CRG9 Dual QHD Curved QLED. Thanks to PowerToys, it’s possible to create multiple (“Fancy”) zones and quickly move apps to a specific zone.

Webcam

When working from home, I’m convinced it’s still super important being able to see eachother. The reasons I purchased the Logitech BRIO are:

  1. Support for Windows Hello (no more typing of passwords / pins)
  2. 4K resolution
  3. Great colors / lighting, even when I turn off the lights in the office

Chair

I’ve put the chair at the bottom. It still deserves a place in this hardware setup for a few reasons:

  • Not everyone wants to or can stand all day
  • It’s a great chair

Whenever I was young, I knew it was very important to purchase a good ergonomic chair. At the moment, it collects dust in my office, and I only use it whenever I don’t feel very well (only reason for me to sit behind my desk instead of standing / biking). The chair I purchased is the Haworth Zody.

Automate UWP submissions using Cake

Finally we can automate uwp submissions using Cake!

This blog post has been in the makings for about a year now. But due to some technical store issues, it was delayed for a while. But no fear, the time has finally come here!

While working on several UWP apps for the Microsoft store, I found the deployment part very tedious. Especially building the 3 (x86, x64 and ARM) packages with the native toolchain were taking a long time (about 20 minutes).

I had a few ultimate goals while developing UWP apps:

  1. Get rid of the native compilation
  2. Automate the store submission

This pipeline (image taken from the build configuration in Continua CI) was the ultimate goal:

image

Getting rid of native compilation

Luckily for me, I didn’t have to do a lot of research on this front. Oren Novotny took care of this for the community by investigating this.

To summarize his hard work, you will need to use the following property values:

Property Value
UapAppxPackageBuildMode CI
AppxBundlePlatforms x86|x64|ARM
AppxBundle Always

Automate the store deployment

Next up was to automate the deployment to the store. I wanted to be able to trigger a build and only had to check the newly created deployment in the Windows Microsoft Store to submit it. For me, a logical first step was to take a look at Cake, which is an open-source tool (with lots of add-ons) for automating builds. There are several things that need automation in the deployment process:

  1. Determine the version number – GitVersion
  2. Update the version number in the appxmanifest
  3. Build the app for each target platform (x86, x64 and ARM), but without the slow native compilation
  4. Create a submission in the Microsoft Store (based on the previous one) and upload the new packages

Determine the version number

To determine the version number of the app, you can simply tag a specific commit with the version number and use GitVersion. I won’t go into too much details for this blog post.

Update the version number in the appxmanifest

At this stage, we have the version number and need to update it. Since this is UWP, updating the AssemblyInfo isn’t sufficient. To overcome this in Cake, one can use the MagicChunks add-on for Cake:

Building the app

Below is the code to build the app using Cake without native compilation:

Submitting the app

Unfortunately, due to the level of popularity of the Microsoft Store, there was no add-on yet for submissions. But now there is the Cake.WindowsAppStore add-in, making it very easy to submit the app to the store. The following values are required:

  • Windows Store App Id
  • Windows Store Client Id
  • Windows Store Client Secret
  • Windows Store Tenant ID

Check the official guide on Microsoft Docs on how to obtain these prerequisites.

Below is the Cake task for the submission:

Conclusion

Achievement unlocked! After over 200 manual submissions, I can finally publish app updates automatically via a build server with an acceptable build duration (45 seconds instead of 5 minutes):

All scripts described in this blog post are open source and can be found at https://github.com/GeertvanHorrik/UwpSubmissionsUsingCake

References

Multi-targeting .NET 4.6, .NET 4.7, UAP 10.0 with a single project

After waiting for the project.json storm to lay down, it was time for me to check whether the new .NET SDK project system was worth checking out. Oh dear, it was! In this post I will try to explain our reasoning to migrate to the new project system and how we overcame some of the issues we encountered during the transition.

Requirements

One of the companies I work for use a large amount of (open source) libraries target .NET 4.5, .NET 4.6 and .NET 4.7. The reason we supported 3 different target frameworks per library is that it allowed us to switch the runtime of the (WPF) apps at any time and the libraries would be ready for it. However, a big downside of this is that loading the solution takes a long time, and everything is duplicated as you can see in the picture below:

While we are (considering to) making the transition to UWP, this would introduce a 4th platform project, meaning we would have 4 + 1 (for the shared project) = 5 projects per library.

image

Time to make a change! After reading the very promising blog post by Oren Novotny, I decided to make the jump and try and convert all the libraries to the new SDK project to achieve the following goals:

  • Single project to target multiple platforms (at the moment .NET 4.6, .NET 4.7, UAP 10.0 and .NET Standard 2.0, but more could easily be added in the future)
  • Update the build scripts from FinalBuilder to Cake (make it easier for open source contributors to work with)
  • Automatically generate the NuGet packages via MSBuild instead of FinalBuilder (again to make it easier for open source contributors to work with)

For this blog post, I will be using a fake repository named Ghk.MultiTargeting as an example. Note that this project is useless, but contains per-platform xaml code and shared code-behind.

Project differences compared to the original template

Compared to the original multi-targeting example, we made the following changes.

Project defines

To make sure I could still use the defines we invested in (to maximize code-sharing, we use a lot of #if in code shared between WPF and UWP). This project creates the following defines:

  • .NET 4.6 => NET; NET46
  • .NET 4.7 => NET; NET47
  • UAP 10.0 => UAP; NETFX_CORE
  • .NET Standard 2.0 => NS; NS20; NETSTANDARD; NETSTANDARD2_0

Include solution assembly info

The project structure adds this line to the project to include the SolutionAssemblyInfo and GlobalSuppressions files which are in the root of the solution.

Allow shared code-behind (e.g. MyView.xaml.cs) with a *per platform* view (e.g. MyView.xaml)

To allow sharing of code-behind of a view (for example, for custom controls), we need to to a bit of hacking. We create the view inside each platform specific view directory:

  • Platforms\net\Views\MyView.xaml (+ .cs)
  • Platforms\uap10.0\Views\MyView.xaml (+ .cs)

After creating the views, we will need to customize the code-behind to add a partial method:

Next, we create a partial code-behind class inside the regular views folder that contains the shared code:

  • Views\MyView.xaml.cs

This view should contain the following code and you can share your code-behind but have per-platform xaml files:

As an example, I added a dependency property in the shared code-behind that shows how to deal with the different platforms in shared code using defines.

Final project structure

Below is the final project structure that can serve as a reference.

Note that it is recommended to check out the latest version in the example repository.

Bonus: Cake deployments

Since we also migrated to using Cake as build script tooling, this is a good opportunity to take a look at Cake as well. I added the full build scripts we use for our components in the example repository. Note that you only have to change the variables in build.cake in the root and all should be updated.

References