<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/">
  <author>
    <name>Robin Douglas</name>
  </author>
  <id>https://rbd.dev/feed.xml</id>
  <link href="https://rbd.dev"/>
  <link href="https://rbd.dev/feed.xml"
    rel="self"
    type="application/atom+xml"/>
  <title>rbd</title>
  <updated>2026-07-07T00:00:00+00:00</updated>
  <entry>
    <content type="html">&lt;p&gt;&lt;em&gt;Warning: bad Factor code contained within.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As an escape from AI, I recently started programming in Factor. As well as being a very interesting departure from C-like languages, AI kind of sucks at writing in it - keeping me from reaching for that crutch.&lt;/p&gt;

&lt;p&gt;After messing around a little bit, getting used to the syntax (which was much easier than I expected thanks to its simplicity and the resulting consistency), I decided upon a first project: I would resurrect this blog, once powered by Jekyll, with a custom generator.&lt;/p&gt;

&lt;h2 id=&quot;the-first-hurdle&quot;&gt;The first hurdle&lt;/h2&gt;

&lt;p&gt;No package manager… and no markdown package.&lt;/p&gt;

&lt;p&gt;So… I sat down and started writing a parser from scratch. This was a good exercise, and it was during this that the concatenative style really clicked for me. One eureka moment was realising how much more readable and expressive code could be when following the sorts of functional patterns we often use in Swift: &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, etc (I had initially reached for recursion 🤷‍♂️).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:: parse-md-line ( string -- md-line )
  ! ( -- line-type slice )
  all-line-types
  [
    line-type-pattern string
    swap &amp;lt;regexp&amp;gt;
    first-match
  ]
  map-find
  swap
  
  ! ( slice -- string )
  1array missing-slices
  &quot;&quot; join

  md-line boa
;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;rescued-by-the-standard-library&quot;&gt;Rescued by the standard library&lt;/h2&gt;

&lt;p&gt;While Factor doesn’t have a package manager, what it does have is a great standard library.&lt;/p&gt;

&lt;p&gt;After beginning to get frustrated by my lack of progress, I discovered the fantastic &lt;a href=&quot;https://docs.factorcode.org/content/article-peg.ebnf.tokenizers.html&quot;&gt;EBNF package&lt;/a&gt; after watching &lt;a href=&quot;https://www.youtube.com/watch?v=f_0QlhYlS8g&quot;&gt;Factor: an extensible interactive language&lt;/a&gt; by Factor’s creator, Slava Pestov. With this vocab (library) at my disposal, I binned all my work up to this point, and started again 🙂. In a fraction of the time I had spent on the previous version I had ~90% of a parser.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;EBNF: markdown [=[
  text = [^*_[\n]+
    =&amp;gt; [[ &amp;gt;string text swap 2array ]]
  char = [^\n]
    =&amp;gt; [[ 1string text swap 2array ]]
  link-text = [^*_[\]\n]+
    =&amp;gt; [[ &amp;gt;string text swap 2array ]]
  link-char = [^\]\n]
    =&amp;gt; [[ 1string text swap 2array ]]
  bold = &quot;*&quot;~ (!(&quot;*&quot;) inline)+:xs &quot;*&quot;~
    =&amp;gt; [[ xs &amp;gt;array bold swap 2array ]]
  italic = &quot;_&quot;~ (!(&quot;_&quot;) inline)+:xs &quot;_&quot;~
    =&amp;gt; [[ xs &amp;gt;array italic swap 2array ]]
  link-inline = bold | italic | link-text | link-char
  link = &quot;[&quot;~ link-inline+:label &quot;]&quot;~ &quot;(&quot;~ [^)]+:url &quot;)&quot;~
    =&amp;gt; [[ label &amp;gt;array url &amp;gt;string link -rot 3array ]]
  inline = bold | italic | link | text | char
  h1 = &quot;#&quot;~ &quot; &quot;+~ [^\n]+:t &quot;\n&quot;~
    =&amp;gt; [[ t &amp;gt;string h1 swap 2array ]]
  h2 = &quot;##&quot;~ &quot; &quot;+~ [^\n]+:t &quot;\n&quot;~
    =&amp;gt; [[ t &amp;gt;string h2 swap 2array ]]
  h3 = &quot;###&quot;~ &quot; &quot;+~ [^\n]+:t &quot;\n&quot;~
    =&amp;gt; [[ t &amp;gt;string h3 swap 2array ]]
  ulitem = &quot;*&quot;~ &quot; &quot;+~ inline+:xs &quot;\n&quot;~
    =&amp;gt; [[ xs &amp;gt;array ul-item swap 2array ]]
  olitem = [0-9]+~ &quot;.&quot;~ &quot; &quot;+~ inline+:xs &quot;\n&quot;~
    =&amp;gt; [[ xs &amp;gt;array ol-item swap 2array ]]
  list = (ulitem|olitem)+
    =&amp;gt; [[ &amp;gt;array list swap 2array ]]
  paragraph = inline+:xs &quot;\n&quot;~
    =&amp;gt; [[ xs &amp;gt;array paragraph swap 2array ]]
  blank = &quot; &quot;*~ &quot;\n&quot;~
    =&amp;gt; [[ ignore ]]
  header = h1 | h2 | h3
  block = header | list | paragraph
  document = (blank|block)+
    =&amp;gt; [[ [ ignore = ] reject &amp;gt;array ]]
]=]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For templating, I simply took advantage of Factor’s ability to dynamically evaluate a string of Factor code. Strings wrapped in &lt;code&gt;%%&lt;/code&gt; become quotations (closures) that are expected to push a string onto the stack when called (returning a string). Post metadata uses &lt;code&gt;%%%&lt;/code&gt;, whose quotation instead relies on side effects to set metadata and leaves the stack unchanged.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USING: kernel splitting parser strings math sequences ;
IN: template.parser

&amp;lt;PRIVATE

: parse-quotation ( slice -- quotation )
  &amp;gt;string
  split-lines
  parse-lines
;

: quote-text ( slice -- quotation )
  &amp;gt;string [ ] curry
;

: parse-body ( string -- blocks )
  &quot;%%&quot; split-subseq
  [
    2 mod 0 = [
      quote-text
    ] [
      parse-quotation
    ] if
  ] map-index
;

PRIVATE&amp;gt;

TUPLE: template meta body ;

: parse-template ( string -- template )
  &quot;%%%\n&quot; split1
  dup [ swap ] unless
  parse-body
  [
    dup [ parse-quotation ] when
  ] dip
  template boa
;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;this-post-was-rendered-by-ruby&quot;&gt;This post was rendered by Ruby&lt;/h2&gt;

&lt;p&gt;Factor is incredibly &lt;em&gt;powerful&lt;/em&gt;. A quotation is just a collection of words (functions), providing similar flexibility to that of Lisp’s homoiconicity. Coupled with its seamless support for macros - it’s a language which will be whatever you want it to be.&lt;/p&gt;

&lt;p&gt;Factor is &lt;em&gt;beautiful&lt;/em&gt;. I realised during the project that its concatenative style is a purer, cleaner way of expressing some of my favourite patterns in Swift and PowerShell: method chaining and piping. Being point-free, it’s physically quicker to make changes to your ‘chains’ than either of those two languages.&lt;/p&gt;

&lt;p&gt;The tooling is amazing. You’re provided with one of the best REPLs I’ve ever used, and are encouraged to conduct all your development through it: scaffold modules and tests, play with and edit code, search documentation. I haven’t done much ‘REPL-driven programming’ before, but the listener has converted me.&lt;/p&gt;

&lt;p&gt;It’s also &lt;em&gt;fast&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;however&quot;&gt;However…&lt;/h3&gt;

&lt;p&gt;You could make most of these points about Ruby too… maybe not about speed 🙂, but certainly power, its metaprogramming capabilities placing it firmly in the same league as Factor - Ruby’s power is just derived from its Smalltalk lineage rather than from Forth (Factor has great OO facilities too - but they don’t feel as seamless as Ruby’s to me).&lt;/p&gt;

&lt;p&gt;I was also becoming concerned about Forth/Factor’s reputation as being ‘write-only’ languages. Readability would likely improve with experience, but even coming back to code I had written the previous evening could prove difficult. &lt;a href=&quot;https://www.forth.com/wp-content/uploads/2018/11/thinking-forth-color.pdf&quot;&gt;Thinking Forth&lt;/a&gt; presents Forth’s stack and point-free style as an aid to modularity:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Forth eliminates from our programs the details of how words are invoked and how data are passed. What’s left? Only the words that describe our problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the same coupling to arguments in C-like languages’ functions exists here too, it’s just hidden. Forth words are coupled to the stack order - the order of their positional arguments. I believe the more explicit coupling allowed in Ruby, of non-positional argument names, is more accommodating to change and re-use.&lt;/p&gt;

&lt;h3 id=&quot;in-the-end&quot;&gt;In the end&lt;/h3&gt;

&lt;p&gt;I tired of fixing edge cases in my parser, and the allure of Ruby got the better of me (or perhaps I’m just fickle). I grabbed Kramdown and ERB. Much less work… after spending an afternoon configuring Pry and Neovim to provide a fraction of the listener experience 😅.&lt;/p&gt;

&lt;p&gt;I found myself omitting a lot of brackets.&lt;/p&gt;

&lt;p&gt;(much to Rubocop’s disgust)&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/to-factor-and-back-again.html</id>
    <link href="https://rbd.dev/posts/to-factor-and-back-again.html"/>
    <published>2026-07-07T00:00:00+00:00</published>
    <summary>Warning: bad Factor code contained within...</summary>
    <title>To Factor and Back Again</title>
    <updated>2026-07-07T00:00:00+00:00</updated>
    <dc:date>2026-07-07T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;SwiftUI, announced yesterday at WWDC, is very cool 🤓. Allowing you to create your UI with a declarative style it seems to reduce a lot of boiler plate code. And as mentioned in a &lt;a href=&quot;https://robindouglas.uk/flutter/dart/mobile/2019/01/30/Flutter-Experiment.html&quot;&gt;post&lt;/a&gt; I wrote about Flutter (which also adopts a declarative style), I think it will naturally encourage reusability and cleaner code.&lt;/p&gt;

&lt;p&gt;For the chance to mess around with it a bit, I &lt;a href=&quot;https://github.com/robin1996/SwiftUI_OMDb_Client&quot;&gt;reproduced&lt;/a&gt; some of the UIKit OMDb client I talked about in my previous &lt;a href=&quot;https://robindouglas.uk/swift/xcode/mobile/2019/05/24/Custom-Tab-Bar-Controller.html&quot;&gt;post&lt;/a&gt;. Although it took a little getting used to, the number of lines for features I reproduced in SwiftUI were generally reduced. And, although I’m sure what I wrote won’t match future best practices, I think I preferred the style of the code I wrote with SwiftUI to that with UIKit.&lt;/p&gt;

&lt;h2 id=&quot;xcode&quot;&gt;XCode&lt;/h2&gt;

&lt;p&gt;Although I’ve not yet had a go with some of the new XCode features related to SwiftUI (they need Mac OS Catalina), the support for SwiftUI looks even better than the support for Flutter on Android studio. The hot reload and new ‘interface builder’ that provides shortcuts but &lt;em&gt;doesn’t&lt;/em&gt; make you give up the power of programmatically defining your UI looks incredible.&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/swiftui-omdb-search-experiment.html</id>
    <link href="https://rbd.dev/posts/swiftui-omdb-search-experiment.html"/>
    <published>2019-06-05T00:00:00+00:00</published>
    <summary>SwiftUI, announced yesterday at WWDC, is very cool 🤓. Allowing you to create your UI with a declarative style it seems to reduce a lot of boiler plate code. And...</summary>
    <title>SwiftUI OMDb search experiment</title>
    <updated>2019-06-05T00:00:00+00:00</updated>
    <dc:date>2019-06-05T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;The &lt;a href=&quot;https://1.1.1.1&quot;&gt;1.1.1.1 App&lt;/a&gt; uses an interesting way of navigating to and from its settings menu. It performs the role of a tab bar, but possibly looks a lot cleaner than a tab bar would with only two items.&lt;/p&gt;

&lt;p&gt;To accomplish a similar navigation I wrote a simple subclass of &lt;code&gt;UIViewController&lt;/code&gt; that has two child VCs and swaps between displaying each of their views using a persistent &lt;code&gt;UIButton&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Find the project &lt;a href=&quot;https://github.com/robin1996/OMDb-client&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/BXhWKgONfsE&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
</content>
    <id>https://rbd.dev/posts/custom-tab-bar-controller.html</id>
    <link href="https://rbd.dev/posts/custom-tab-bar-controller.html"/>
    <published>2019-05-24T00:00:00+00:00</published>
    <summary>The 1.1.1.1 App uses an interesting way of navigating to and from its settings menu. It performs the role of a tab bar, but possibly looks a lot cleaner than...</summary>
    <title>Custom ‘tab bar controller’ for two child VCs</title>
    <updated>2019-05-24T00:00:00+00:00</updated>
    <dc:date>2019-05-24T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;With all the buzz around flutter at the moment, especially among the android developers at work I find, I thought I’d have a go at making a simple app. &lt;a href=&quot;https://github.com/robin1996/flutter_task_manager&quot;&gt;So I made a to do list app of course&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;initial-impressions&quot;&gt;Initial impressions&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I am probably biased&lt;/strong&gt;. Maybe the development cost savings &lt;em&gt;are&lt;/em&gt; worth it, but overall, I definitely don’t think it approaches the native Xcode development for iOS at least. And, although the apps look good, to me they just don’t feel as nice on iOS, and there are things that make them pretty destingishable.&lt;/p&gt;

&lt;p&gt;However! The hot reload was really cool, and definitely saves a lot of time.  I also quite like the step away from ‘Storyboard-like’ development, I’ve been trying to use storyboards less in my Xcode/swift development anyway, I think it promotes reusability can produce simpler code.&lt;/p&gt;

&lt;h2 id=&quot;editors&quot;&gt;Editors&lt;/h2&gt;

&lt;p&gt;Another nice thing is not being as chained to Xcode. Although I think Xcode is pretty great, I prefer using Vim keybindings which is impossible or a pain to get working with Xcode. Android studio and the fist party plugin for VSCode both work great &lt;strong&gt;and&lt;/strong&gt; allow for Vim keybindings 🥳.&lt;/p&gt;

&lt;p&gt;I like Vim a lot though, so I spent way longer than was worth it setting up neovim for flutter development and it did a pretty good job thanks to &lt;a href=&quot;https://github.com/autozimu/LanguageClient-neovim&quot;&gt;LanguageClient-neovim&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://pub.dartlang.org/packages/dart_language_server&quot;&gt;dart_language_server&lt;/a&gt;, &lt;a href=&quot;https://github.com/Shougo/deoplete.nvim&quot;&gt;deoplete.nvim&lt;/a&gt; and &lt;a href=&quot;https://github.com/dart-lang/dart-vim-plugin&quot;&gt;dart-vim-plugin&lt;/a&gt;.&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/flutter-experiment.html</id>
    <link href="https://rbd.dev/posts/flutter-experiment.html"/>
    <published>2019-01-30T00:00:00+00:00</published>
    <summary>With all the buzz around flutter at the moment, especially among the android developers at work I find, I thought I’d have a go at making a simple app. So...</summary>
    <title>Flutter Experiment</title>
    <updated>2019-01-30T00:00:00+00:00</updated>
    <dc:date>2019-01-30T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;One thing I often found myself doing with the VMWare vSphere client is resetting VMs to their previous snapshot, therefore ‘cleaning’ them. I’ve since started using PowerCLI for almost everything, however, I couldn’t find a simple way to use if for resetting VMs, &lt;em&gt;the built-in cmdlets requiring you to name a specific snapshot&lt;/em&gt; (please let me know if there’s something I’ve missed!).&lt;/p&gt;

&lt;p&gt;To get around this I wrote a simple function that will just reset any VM to its most recent snapshot, which I keep, along with some other PowerCLI related functions, in a PowerShell module that gets imported whenever I connect to the server:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;function Reset-VMToCurrentSnapshot {
    [CmdletBinding()]
    param (
        [parameter(Mandatory = $true,
        ValueFromPipeline)]
        [string] $VM,

        [parameter(Mandatory = $false)]
        [switch] $confirm = $true
    )

    PROCESS {
        $doit = $true
        $snap = Get-Snapshot -VM $VM | where {$_.IsCurrent -eq $true}
        if (((Get-VM $VM).PowerState -eq &quot;PoweredOn&quot;) -and $confirm) {
            $title = &quot;Revert $VM to $snap&quot;
            $message = &quot;$VM is powered on, are you sure you want to revert it?&quot;
            $yes = New-Object `
                System.Management.Automation.Host.ChoiceDescription &quot;&amp;amp;Yes&quot;, `
                &quot;Revert $VM to $snap.&quot;
            $no = New-Object `
                System.Management.Automation.Host.ChoiceDescription &quot;&amp;amp;No&quot;, `
                &quot;Don&#39;t revert $VM.&quot;
            $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
            $result = $host.ui.PromptForChoice($title, $message, $options, 0)
            switch ($result)
                {
                    0 {
                        Write-Verbose &quot;Reverting $VM.&quot;
                    }
                    1 {
                        Write-Host &quot;Leaving $VM as is.&quot;
                        $doit = $false
                    }
                }
        }

        if ($doit) {
            Write-Verbose &quot;Setting $VM to $snap...&quot;
            Set-VM -VM $VM -SnapShot $snap -Confirm:$false
            Write-Verbose &quot;Done!&quot;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content>
    <id>https://rbd.dev/posts/powercli-reset-vm.html</id>
    <link href="https://rbd.dev/posts/powercli-reset-vm.html"/>
    <published>2018-06-21T00:00:00+00:00</published>
    <summary>One thing I often found myself doing with the VMWare vSphere client is resetting VMs to their previous snapshot, therefore ‘cleaning’ them. I’ve since started using PowerCLI for almost everything...</summary>
    <title>PowerCLI: Reset VM to Current Snapshot</title>
    <updated>2018-06-21T00:00:00+00:00</updated>
    <dc:date>2018-06-21T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;At work, I’ve recently had the need to create simple desktop programs for Windows to provide more effective user interfaces to configure and launch a number of scripts. And, mainly because I’ve been really enjoying using the language lately, I decided to use Go to write it… &lt;em&gt;Problem&lt;/em&gt; is, there aren’t very many libraries available to do this that are stable &lt;em&gt;and&lt;/em&gt; complete! In this blog post, I hope to highlight some of the more promising ones.&lt;/p&gt;

&lt;h2 id=&quot;qt-bindings&quot;&gt;Qt bindings&lt;/h2&gt;

&lt;p&gt;There are a couple of projects on Github claiming almost complete Go bindings for &lt;a href=&quot;https://www.qt.io/&quot;&gt;Qt&lt;/a&gt;. Although I’ve found Qt to be very useful for similar things in the past, the ~35GBs for Qt itself, and relatively complex setup were enough to put me off even trying these libraries out. &lt;em&gt;But they do exist!&lt;/em&gt; There is a nice list of libraries for building GUI programs &lt;a href=&quot;https://github.com/avelino/awesome-go#gui&quot;&gt;here&lt;/a&gt;, you’ll be able to find the more popular Qt bindings there, as well as many other options.&lt;/p&gt;

&lt;h2 id=&quot;walk&quot;&gt;Walk&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/lxn/walk&quot;&gt;&lt;em&gt;Windows Application Library Kit&lt;/em&gt;&lt;/a&gt;. This one looked very promising at first, it’s Windows-specific and can be set up using &lt;code&gt;go get&lt;/code&gt;. I’ve also read a few articles praising it. My personal experience was okay, I think I could have used it if I’d needed to. It isn’t the most complete but it’s not bad, and its declarative subpackage can make code actually arranging the interface widgets more readable than other options. In the end, it still had some of the same problems as other options and I’d prefer something with a bit better documentation.&lt;/p&gt;

&lt;h2 id=&quot;ui&quot;&gt;ui&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/andlabs/ui&quot;&gt;ui&lt;/a&gt; is a very simple cross-platform GUI library based on &lt;a href=&quot;https://github.com/andlabs/libui&quot;&gt;libui&lt;/a&gt; (a C GUI library by the same author). Ultimately, it’s the option I chose to use. I found it very easy to set up (it also supports &lt;code&gt;go get&lt;/code&gt;) and to use. It got the job done! The main drawback, as with most of the options, is completeness. As of writing this post, there is no text area widget (however, &lt;a href=&quot;https://github.com/ProtonMail/ui&quot;&gt;another fork&lt;/a&gt; of the project has one!). I ran into other issues due to lacking features but there was always a solution/workaround easy enough to be found.&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/golang-gui-libraries.html</id>
    <link href="https://rbd.dev/posts/golang-gui-libraries.html"/>
    <published>2018-06-20T00:00:00+00:00</published>
    <summary>At work, I’ve recently had the need to create simple desktop programs for Windows to provide more effective user interfaces to configure and launch a number of scripts. And, mainly...</summary>
    <title>GoLang GUI Libraries</title>
    <updated>2018-06-20T00:00:00+00:00</updated>
    <dc:date>2018-06-20T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;With a lot of scripts, automating repetitive tasks is the goal, and therefore user interaction should be minimal. That being said, PowerShell is rich in ways to handle it.&lt;/p&gt;

&lt;h2 id=&quot;pauses&quot;&gt;Pauses&lt;/h2&gt;

&lt;p&gt;For PowerShell 3 and up you can just do &lt;code&gt;Pause&lt;/code&gt; to pause until the user presses enter.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Press Enter to continue...: _
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For earlier versions, you could define a ‘Pause’ function with &lt;code&gt;Read-Host&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;function Pause {
    Read-Host &quot;Press Enter to continue...&quot; | Out-Null
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Fall back to using &lt;code&gt;cmd.exe&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;function Pause {
    cmd /c &quot;pause&quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I’ve also seen people write pause functions to continue on any key press (not just enter) like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;function Pause {
    Write-Host &quot;Press any key to continue...&quot;
    do {
        $x = $host.UI.RawUI.ReadKey(&quot;NoEcho,IncludeKeyUp&quot;)
    } while (9, 16, 17, 18, 91, 92, 144 -contains $x.VirtualKeyCode)
    # ignore some keys (Tab, Shift, Ctrl, Alt, WinL, WinR, NumLock) sent by certain events when running via RDP
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;prompt-for-choice&quot;&gt;Prompt for Choice&lt;/h2&gt;

&lt;p&gt;Another common way of getting user interaction is presenting a list of options using &lt;code&gt;$host.UI.PromptForChoice&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;$title = &quot;Version number&quot;
$message = &quot;Is $version the correct version number?&quot;

$yes = New-Object System.Management.Automation.Host.ChoiceDescription &quot;&amp;amp;Yes&quot;, &quot;Use version number $version.&quot;
$no = New-Object System.Management.Automation.Host.ChoiceDescription &quot;&amp;amp;No&quot;, &quot;Enter a version number manually.&quot;

$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

$result = $host.ui.PromptForChoice($title, $message, $options, 0)

switch ($result)
    {
        0 {
            Write-Host &quot;Yes!&quot;
        }
        1 {
            Write-Host &quot;No!&quot;
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will give your user an interface that looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Version number
Is &amp;lt;someVersionNumber&amp;gt; the correct version number?
[Y] Yes  [N] No  [?] Help (default is &quot;Y&quot;):
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They can then enter &lt;code&gt;y&lt;/code&gt; for yes, &lt;code&gt;n&lt;/code&gt; for no etc.&lt;/p&gt;

&lt;h2 id=&quot;guis&quot;&gt;GUIs&lt;/h2&gt;

&lt;p&gt;If you’re using &lt;em&gt;Windows&lt;/em&gt; PowerShell you also have the option for user interaction through GUIs. The cmdlet &lt;code&gt;Out-GridView&lt;/code&gt; lets you visually filter or select objects, I’ve previously written a &lt;a href=&quot;http://robindouglas.uk/powershell/2017/12/11/PowerShell-git-branch-GridView.html&quot;&gt;post&lt;/a&gt; specifically on &lt;code&gt;Out-GridView&lt;/code&gt;. Having access to full .NET also allows you to easily create bespoke GUIs using Windows Forms or WPF, I’ve also previously written a &lt;a href=&quot;http://robindouglas.uk/powershell/2017/12/13/PowerShell-XAML-GUI.html&quot;&gt;post&lt;/a&gt; on this.&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/powershell-user-interaction.html</id>
    <link href="https://rbd.dev/posts/powershell-user-interaction.html"/>
    <published>2018-04-20T00:00:00+00:00</published>
    <summary>With a lot of scripts, automating repetitive tasks is the goal, and therefore user interaction should be minimal. That being said, PowerShell is rich in ways to handle it...</summary>
    <title>PowerShell User Interaction</title>
    <updated>2018-04-20T00:00:00+00:00</updated>
    <dc:date>2018-04-20T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Using Vim with and to write PowerShell!&lt;/p&gt;

&lt;h2 id=&quot;not-as-good-as-vscode&quot;&gt;Not as good as VSCode&lt;/h2&gt;

&lt;p&gt;When it comes to writing &lt;em&gt;large&lt;/em&gt; PowerShell scripts, VSCode is plain better, thanks to Microsoft’s &lt;a href=&quot;https://github.com/PowerShell/vscode-powershell&quot;&gt;extension&lt;/a&gt; for PowerShell (there are &lt;a href=&quot;https://github.com/VSCodeVim/Vim&quot;&gt;extensions&lt;/a&gt; to emulate Vi key bindings too). To be honest, the PowerShell ISE is also a better bet. &lt;strong&gt;But!&lt;/strong&gt; There are some cases where it can make sense to use Vim, mostly when you want to quickly write a short script or make a small change to a pre-existing script. Vim launches faster than VSCode (not that VSCode is at all slow) and, provided you know the correct key bindings, can often be quicker to perform the edit with. &lt;em&gt;Or maybe you just like using Vim!&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;neovim&quot;&gt;Neovim&lt;/h2&gt;

&lt;p&gt;If you’re wanting to use Vim to write PowerShell, even with the introduction of cross-platform PowerShell core, chances are you’re on Windows. If that’s the case I recommend using Neovim with the Neovim-Qt GUI. Using a GUI just feels more natural on Windows and Neovim-Qt is cleaner out-of-the-box than gVim. I’ve also run into fewer problems running Neovim than I have with Vim when on Windows.&lt;/p&gt;

&lt;h2 id=&quot;windows-clipboard&quot;&gt;Windows clipboard&lt;/h2&gt;

&lt;p&gt;To get &lt;kbd&gt;Ctrl&lt;/kbd&gt;&lt;kbd&gt;c&lt;/kbd&gt;/&lt;kbd&gt;v&lt;/kbd&gt; copy/paste working for Neovim-Qt &lt;em&gt;when in insert mode&lt;/em&gt; just add &lt;code&gt;source $VIMRUNTIME/mswin.vim&lt;/code&gt; to your vimrc file.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;On Windows, Neovim’s vimrc file is located at &lt;code&gt;%USERPROFILE%\AppData\Local\nvim\init.vim&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;setting-posh-as-vims-shell&quot;&gt;Setting Posh as Vim’s shell&lt;/h2&gt;

&lt;p&gt;By default, shell commands use &lt;code&gt;cmd.exe&lt;/code&gt;, to use PowerShell instead just add the following snippet to your vimrc file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set shell=powershell.exe
set shellcmdflag=-NoProfile\ -NoLogo\ -NonInteractive\ -Command
set shellpipe=|
set shellredir=&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding &lt;code&gt;-NoProfile\&lt;/code&gt; when setting &lt;code&gt;shellcmdflag&lt;/code&gt; stops PowerShell from loading your profile every time you run a shell command from Vim, e.g. &lt;code&gt;:!ls&lt;/code&gt;, but still loads it when creating a Neovim terminal buffer, &lt;code&gt;:terminal&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;ps1vim&quot;&gt;ps1.vim&lt;/h2&gt;

&lt;p&gt;To add syntax highlighting, I use &lt;a href=&quot;https://github.com/PProvost/vim-ps1&quot;&gt;this&lt;/a&gt; plugin. It does what it says on the tin! I recommend using &lt;a href=&quot;https://github.com/junegunn/vim-plug&quot;&gt;vim-plug&lt;/a&gt; for managing plugins if you’re not using something already.&lt;/p&gt;

&lt;h2 id=&quot;abbreviations&quot;&gt;Abbreviations&lt;/h2&gt;

&lt;p&gt;It’s good practice to use a cmdlet’s full name when writing PowerShell scripts so I like to set up abbreviations for my most frequently used aliases e.g.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:ab ls Get-ChildItem
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since abbreviations activate just the same when writing comments or strings (you might not want them to), I avoid setting them for cmdlet aliases that I rarely use.&lt;/p&gt;

&lt;h3 id=&quot;reuse&quot;&gt;Reuse&lt;/h3&gt;

&lt;p&gt;As I &lt;em&gt;don’t&lt;/em&gt; want these abbreviations when using vim for anything but PowerShell I put them in &lt;code&gt;ftplugin\ps1_ab.vim&lt;/code&gt; instead of my vimrc file. They are then only loaded when the filetype is ‘ps1’. Because I have ps1.vim installed (see above) the abbreviations will be picked up for other PowerShell file extensions too, e.g. &lt;code&gt;.psm1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the sake of using vim-plug to manage &lt;code&gt;ps1_ab.vim&lt;/code&gt;, I keep it in a &lt;a href=&quot;https://github.com/robin1996/posh-ab&quot;&gt;Git repository&lt;/a&gt; and just add &lt;code&gt;Plug &#39;robin1996/posh-ab&#39;&lt;/code&gt; to my vimrc file.&lt;/p&gt;

&lt;h2 id=&quot;my-full-vimrc-file&quot;&gt;My full vimrc file&lt;/h2&gt;

&lt;p&gt;{% gist 0238fc1cb42a9b586cd0fc6e6a4fadc6 %}&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/powershell-with-vim.html</id>
    <link href="https://rbd.dev/posts/powershell-with-vim.html"/>
    <published>2018-04-05T00:00:00+00:00</published>
    <summary>Using Vim with and to write PowerShell...</summary>
    <title>PowerShell with Vim</title>
    <updated>2018-04-05T00:00:00+00:00</updated>
    <dc:date>2018-04-05T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Local Durham artist, &lt;em&gt;Mike Attewell&lt;/em&gt;, recounts the erosion of the welfare state during his lifetime for &lt;a href=&quot;https://www.theguardian.com/global/2018/mar/06/good-to-meet-you-mike-attewell&quot;&gt;this week’s&lt;/a&gt; Guardian ‘Good To Meet You’.&lt;/p&gt;

&lt;p&gt;For more of his work see &lt;a href=&quot;http://mike-attewell.co.uk&quot;&gt;mike-attewell.co.uk&lt;/a&gt;.&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/mike-attewell.html</id>
    <link href="https://rbd.dev/posts/mike-attewell.html"/>
    <published>2018-03-09T00:00:00+00:00</published>
    <summary>Local Durham artist, Mike Attewell, recounts the erosion of the welfare state during his lifetime for this week’s Guardian ‘Good To Meet You...</summary>
    <title>Mike Attewell on Britain&#39;s Decline</title>
    <updated>2018-03-09T00:00:00+00:00</updated>
    <dc:date>2018-03-09T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Just for the sake of writing a Github &lt;a href=&quot;https://gist.github.com&quot;&gt;Gist&lt;/a&gt; I decided to post some of the notes I made when first learning PowerShell.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/robdou/2d94b5c86e9a9f7acc3ca92a03e611f6.js&quot;&gt;&lt;/script&gt;

</content>
    <id>https://rbd.dev/posts/powershell-notes-gist.html</id>
    <link href="https://rbd.dev/posts/powershell-notes-gist.html"/>
    <published>2018-02-12T00:00:00+00:00</published>
    <summary>Just for the sake of writing a Github Gist I decided to post some of the notes I made when first learning PowerShell...</summary>
    <title>PowerShell Notes Gist</title>
    <updated>2018-02-12T00:00:00+00:00</updated>
    <dc:date>2018-02-12T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Hello! Today I wanted to write a bit about creating GUIs/forms as part of PowerShell scripts. Sometimes having a GUI rather than just a command line interface for scripts can be beneficial, they can often be more intuitive to use and can give the user more of a ‘bird’s eye view’ of the script’s controls than just a succession of questions or script parameters. Plus, who doesn’t want to spend hours adding shiny GUIs to their scripts anyway?&lt;/p&gt;

&lt;p&gt;I recently set up a GUI for controlling our scripted build process at work (we will be moving to a CI server soon… hopefully). And, since most of the scripts are written in PowerShell and I don’t know C# I thought it made sense to put the GUI in PowerShell too.&lt;/p&gt;

&lt;h2 id=&quot;tools&quot;&gt;Tools&lt;/h2&gt;

&lt;p&gt;As &lt;em&gt;Windows&lt;/em&gt; PowerShell uses the full .Net framework, it has access to both &lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_Forms&quot;&gt;Windows Forms&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_Presentation_Foundation&quot;&gt;WPF&lt;/a&gt;. I chose to go down the WPF route as it allows you to write the GUI itself using XAML rather than fiddling with form objects.&lt;/p&gt;

&lt;p&gt;There are tools available like &lt;a href=&quot;https://www.visualstudio.com/&quot;&gt;Visual Studio&lt;/a&gt; that will let you create your XAML GUI using a GUI, which is probably a lot faster and just all around better than writing the XAML by hand… but I decided to use the program Kaxaml (at the time of writing this post their website is down, but you can find the project’s GitHub &lt;a href=&quot;https://github.com/thinkpixellab/kaxaml&quot;&gt;here&lt;/a&gt;). Kaxaml allows you to write XAML and then preview it… it’s free!&lt;/p&gt;

&lt;h2 id=&quot;adding-the-xaml&quot;&gt;Adding the XAML&lt;/h2&gt;

&lt;p&gt;Once you have written your GUI in XAML you can add the code to your PowerShell script as an XML object using a here-string.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;[void][System.Reflection.Assembly]::LoadWithPartialName(&#39;presentationframework&#39;)
[xml]$xamlCode = @&#39;
&amp;lt;Window
xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
Title=&quot;Test GUI&quot; WindowStartupLocation=&quot;CenterScreen&quot;&amp;gt;
    &amp;lt;Grid Margin=&quot;0,5,0,0&quot;&amp;gt;
        &amp;lt;Grid.RowDefinitions&amp;gt;
            &amp;lt;RowDefinition Height=&quot;auto&quot;/&amp;gt;
            &amp;lt;RowDefinition Height=&quot;auto&quot;/&amp;gt;
            &amp;lt;RowDefinition Height=&quot;auto&quot;/&amp;gt;
        &amp;lt;/Grid.RowDefinitions&amp;gt;
            &amp;lt;Label Grid.Row=&quot;0&quot; Content=&quot;Hello World!!!!!&quot;/&amp;gt;
            &amp;lt;ComboBox Grid.Row=&quot;1&quot; Name=&quot;testCB&quot;/&amp;gt;
            &amp;lt;Button Grid.Row=&quot;2&quot; Name=&quot;testBtn&quot; Content=&quot;Test&quot;/&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&#39;@
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You then need to have PowerShell read the XML object and create the GUI object from it.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;$reader = (New-Object System.Xml.XmlNodeReader $xamlCode)
$GUI = [Windows.Markup.XamlReader]::Load($reader)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;connecting-functionality&quot;&gt;Connecting functionality&lt;/h2&gt;

&lt;p&gt;To actually do anything useful with your GUI you’ll want to make its component’s objects easily accessible in PowerShell. A couple of ways to do this are by storing the components you want to use as variables individually, or by parsing your XAML code and storing each of your GUI’s components automatically.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;$xamlCode.SelectNodes(&quot;//*[@Name]&quot;) | ForEach-Object { Set-Variable -Name ($_.Name) -Value $GUI.FindName($_.Name) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a variable for each component using their names in the XAML. You can then use these variables to set/get each component’s properties.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;$testCB.ItemsSource = &quot;Option 1&quot;, &quot;Option 2&quot;, &quot;Option 3!!&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or add events.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;$testBtn.Add_Click({
    Write-Host $testCB.Text
})
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;showing-the-gui&quot;&gt;Showing the GUI&lt;/h2&gt;

&lt;p&gt;Finally, to show your GUI, just call &lt;code&gt;ShowDialog&lt;/code&gt; on its object.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;$GUI.ShowDialog() | out-null
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tada!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/E0HeTgh.png&quot; alt=&quot;Tada&quot; /&gt;&lt;/p&gt;
</content>
    <id>https://rbd.dev/posts/powershell-xaml-gui.html</id>
    <link href="https://rbd.dev/posts/powershell-xaml-gui.html"/>
    <published>2017-12-13T00:00:00+00:00</published>
    <summary>Hello! Today I wanted to write a bit about creating GUIs/forms as part of PowerShell scripts. Sometimes having a GUI rather than just a command line interface for scripts can...</summary>
    <title>PowerShell XAML GUI</title>
    <updated>2017-12-13T00:00:00+00:00</updated>
    <dc:date>2017-12-13T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Hello! Today, I needed a way to easily input a branch name into a PowerShell script. To do this, I decided to use what is easily the most fun cmdlet: &lt;em&gt;Out-GridView&lt;/em&gt;. This solution would let me select the branch I want to use from a searchable GUI list.&lt;/p&gt;

&lt;p&gt;I first needed the list of branches.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;PS&amp;gt; $dotgit = &quot;C:\Development\Project\.git\&quot;
PS&amp;gt; git --git-dir=$dotgit branch -r | Out-GridView
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;--git-dir=$dotgit&lt;/code&gt; lets me point the command at a git repo without being in it. &lt;strong&gt;-r&lt;/strong&gt; specifies that I want the list of branches on the remote.&lt;/p&gt;

&lt;p&gt;Already we have our list of branches! There are still some improvements that can be made. I have no need for the first line in the list, ‘origin/HEAD -&amp;gt; origin/master’, nor the ‘origin/’ word prefixing every line.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;PS&amp;gt; git --git-dir=$dotgit branch -r | Select-Object -Skip 1 | ForEach-Object {$_.replace(&quot;  origin/&quot;, &quot;&quot;)} | Out-GridView
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Select-Object&lt;/strong&gt; is used to skip the first line. &lt;strong&gt;ForEach-Object&lt;/strong&gt; is used to replace the word ‘origin/’, and the unnecessary white space that comes before it, with an empty string.&lt;/p&gt;

&lt;p&gt;The list itself is now perfect, but I still need to make some changes to Out-GridView so that I can use it to select the branches I want.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;PS&amp;gt; git --git-dir=$dotgit branch -r | Select-Object -Skip 1 | ForEach-Object {$_.replace(&quot;  origin/&quot;, &quot;&quot;)} | Out-GridView -Title &quot;remote branches&quot; -PassThru
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;-PassTrue&lt;/strong&gt; does just this, and any branches I select will now be passed down the pipeline when &lt;em&gt;OK&lt;/em&gt; is clicked. &lt;em&gt;-Title&lt;/em&gt; just sets the window’s title.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;function pickBranch($dotgit) {
    git --git-dir=$dotgit branch -r |
        Select-Object -Skip 1 |
        ForEach-Object {$_.replace(&quot;  origin/&quot;, &quot;&quot;)} |
        Out-GridView -Title &quot;remote branches&quot; -PassThru
}
&lt;/code&gt;&lt;/pre&gt;
</content>
    <id>https://rbd.dev/posts/powershell-git-branch-gridview.html</id>
    <link href="https://rbd.dev/posts/powershell-git-branch-gridview.html"/>
    <published>2017-12-11T00:00:00+00:00</published>
    <summary>Hello! Today, I needed a way to easily input a branch name into a PowerShell script. To do this, I decided to use what is easily the most fun cmdlet...</summary>
    <title>PowerShell git branch GridView</title>
    <updated>2017-12-11T00:00:00+00:00</updated>
    <dc:date>2017-12-11T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Today, as part of a larger script, I needed to write a PowerShell function to check that an assembly’s version number had been properly bumped between two builds of a program. Writing this function should be simple (right?).&lt;/p&gt;

&lt;p&gt;First things first, get the version numbers. I looked at a File Version in Explorer, ‘16.0.255.0’, cool. Went to do the same in PowerShell.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;PS&amp;gt; get-item .\someFile.exe | select VersionInfo | Format-List *

...
FileVersion:        16.00.0255
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;‘16.00.0255’, a bit odd? This particular file was an InstallShield setup.exe which was versioned ‘xx.xx.xxxx’ within the MSI so it didn’t seem too strange of a difference. I then took a look at a few more files, although for the majority of them, their FileVersion in PowerShell matched Explorer, for a few others there were more weird differences. There was sometimes an extra part, sometimes the last part was a seemingly random number and sometimes the last part was just left off altogether. At this point, I started worrying about time, and as such, I Googled it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogs.technet.microsoft.com/askpfeplat/2014/12/07/how-to-correctly-check-file-versions-with-powershell/&quot;&gt;This&lt;/a&gt; blog post by Matthew Reynolds was my salvation. Essentially, the ‘correct’ FileVersion is contained within the VersionInfo property but is slightly out of the way.&lt;/p&gt;

&lt;p&gt;Using Matthew’s example, I wrote this short block to put a corrected version number into the property ‘RealFileVersion’.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;try {
    Update-TypeData -TypeName System.Io.FileInfo -MemberType ScriptProperty -MemberName RealFileVersion -ErrorAction stop -Value {
        New-Object System.Version -ArgumentList @(
            $this.VersionInfo.FileMajorPart
            $this.VersionInfo.FileMinorPart
            $this.VersionInfo.FileBuildPart
            $this.VersionInfo.FilePrivatePart
        )
    }
} catch [System.Management.Automation.RuntimeException] {
    if ($_.Exception.Message -match &quot;^Error in TypeData \`&quot;System.IO.FileInfo\`&quot;: The member RealFileVersion is already present.$&quot;) {
        Write-Warning &quot;Could not add &#39;RealFileVersion&#39; member to &#39;FileInfo&#39; as it already exists.&quot;
    } else {
        Write-Error &quot;An unknown RuntimeException occurred adding the member &#39;RealFileVersion&#39; to the type &#39;FileInfo&#39;!&quot; -ErrorAction Stop
    }
} catch {
    Write-Error &quot;Something went very wrong adding the member &#39;RealFileVersion&#39; to the type &#39;FileInfo&#39;... and it wasn&#39;t a RuntimeException!&quot; -ErrorAction Stop
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now to compare some version numbers! Fun!&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-posh&quot;&gt;function checkBumped ([System.IO.FileInfo]$oldFile, [System.IO.FileInfo]$newFile) {
    foreach ($part in &quot;Major&quot;,&quot;Minor&quot;,&quot;Build&quot;,&quot;Revision&quot;) {
        If ($newFile.RealFileVersion.$part       -gt $oldFile.RealFileVersion.$part) {
            return $true
        } elseif ($newFile.RealFileVersion.$part -lt $oldFile.RealFileVersion.$part) {
            Write-Error &quot;$oldFile has been rolled back.&quot; -ErrorAction Stop
        }
    }
    return $false
}
&lt;/code&gt;&lt;/pre&gt;
</content>
    <id>https://rbd.dev/posts/powershell-file-versions.html</id>
    <link href="https://rbd.dev/posts/powershell-file-versions.html"/>
    <published>2017-12-05T00:00:00+00:00</published>
    <summary>Today, as part of a larger script, I needed to write a PowerShell function to check that an assembly’s version number had been properly bumped between two builds of a...</summary>
    <title>PowerShell File Versions</title>
    <updated>2017-12-05T00:00:00+00:00</updated>
    <dc:date>2017-12-05T00:00:00+00:00</dc:date>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;As my final project at the University of Leeds I built an educational app for iOS using the multi-paradigm programming language swift and Xcode. The app’s purpose is to aid in teaching and learning A-Level Graph Theory and includes functionality for efficiently producing detailed graph drawings and for visualising certain graph algorithms. Throughout the project, I utilised tools such as CocoaPods and Git as well as many of Apple’s frameworks and some third-party ones, most notably the widely used CoreData alternative Realm. The first iteration of the app, ‘GraphBox’, has been published to the iOS App Store and has a promotional web-page available at: &lt;del&gt;http://graphbox.io/&lt;/del&gt;.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/wNVVLxoBSVw&quot; frameborder=&quot;0&quot; allow=&quot;autoplay; encrypted-media&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
</content>
    <id>https://rbd.dev/posts/research-project.html</id>
    <link href="https://rbd.dev/posts/research-project.html"/>
    <published>2017-05-01T00:00:00+00:00</published>
    <summary>As my final project at the University of Leeds I built an educational app for iOS using the multi-paradigm programming language swift and Xcode. The app’s purpose is to aid...</summary>
    <title>Research Project (GraphBox iOS App)</title>
    <updated>2017-05-01T00:00:00+00:00</updated>
    <dc:date>2017-05-01T00:00:00+00:00</dc:date>
  </entry>
  <dc:date>2026-07-07T00:00:00+00:00</dc:date>
</feed>