Shoot yourself in the foot with powershell

I’ve manged to shot myself in the foot in powershell twice lately, therefore I’ve figured I could write down those examples as a warning to future self (and humanity in general).

Without further ado, here they are:


Strong typing can backfire right at you

[string]$x = 'foo'
$x = ($x.ToLower() -eq 'bar')
Write-Output $x
if ($x)
{
    Write-Output "foobar"
}

Writes to console:

False
foobar

If you remove the [string] decorator, it works “sane” (prints just False).

The foot-shooting happens becuase in second line, there is an implicit cast to string, if $x is strongly typed.


The exit codes..

..are interesting, especially if you want to support PS2.0 and use negative values

Apparently, at Win7 times someone at Microsoft thought storing exit codes as unsigned int was a good idea.

PS C:\> Write-Output "exit -2" > test.ps1
PS C:\> powershell -Command '.\test.ps1'
PS C:\> echo $LASTEXITCODE
1
PS C:\> powershell -Command '.\test.ps1; exit $LASTEXITCODE'
PS C:\> echo $LASTEXITCODE
-2
PS C:\> powershell -Version 2.0 -Command '.\test.ps1; exit $LASTEXITCODE'
PS C:\> echo $LASTEXITCODE
65534

I have a strange feeling that this collection will grow bigger eventually..

Snake in PowerShell console buffer

As a part of “discovering” PowerShell, I had an idea to quickly wrap-up a classic snake game. So.. despite of having lots of more urgent tasks on my head at that moment, I of course decided to sacrifice few hours to this task. The result is this:

PowerSnake window

The game can be started with 5 different speeds. So far no “maps” (obstacles) but that may come in the future (to be honest, I am afraid that I’ll waste even more time on this project).

The code to quickly deal with console buffer that I’ve found on poshcode.com was of great help.

The game’s code can be found on my github: https://github.com/spitfire05/PowerSnake

Update: Graphical version has been made (using WinForms), allowing me to pass ‘Operating Systems’ course at my Uni.. emm, yeah. You can find it here: https://github.com/spitfire05/PowerSnakeGFX

xdelta3 in-memory encoding/decoding in .NET (C#)

I’ve recently faced a problem of using xdelta3 for creating binary diffs of in-memory data in my C# code. I couldn’t really find any wrapper/PInvoke code on the web for xdelta3 in C#, so I went to figure out one myself…

First thing I needed, was xdelta3 compiled as win32 dll, so it could be PInvoked from C#. That was pretty easy to achieve with use of xdelta3 source and MinGW:

# In xdelta3 source folder
i686-w64-mingw32-gcc -DSIZEOF_SIZE_T=4 -fPIC -c xdelta3*.c && i686-w64-mingw32-gcc -shared -static-libgcc -Wl,-soname,xdelta3.dll -o xdelta3.dll xdelta3.o

Next, I created wrapper code in C#:

public class xdelta3
    {
        /// <summary>
        /// Sets the maximum buffer size that xdelta3 is allowed to write to.
        /// </summary>
        static readonly int MAX_BUFFER = 32 * 1024 * 1024; // 32 MB

        /// <summary>
        /// Creates xdelta3 patch from source to target.
        /// </summary>
        /// <param name="target">The target of the patch (the outcome of patching).</param>
        /// <param name="source">The source of the patch (what will be patched).</param>
        /// <returns>Xdelta3 patch data.</returns>
        public static byte[] CreatePatch(byte[] target, byte[] source)
        {
            byte[] obuf = new byte[MAX_BUFFER];
            UInt32 obufSize;

            // Call xdelta3 library
            int result = xd3_encode_memory(target, (UInt32)target.Length,
                source, (UInt32)source.Length,
                obuf, out obufSize,
                (UInt32)obuf.Length, 0);

            // Check result
            if (result != 0)
            {
                throw new xdelta3Exception(result);
            }

            // Trim the output
            byte[] output = new byte[obufSize];
            Buffer.BlockCopy(obuf, 0, output, 0, (int)obufSize);

            return output;
        }

        /// <summary>
        /// Applies xdelta3 patch to source.
        /// </summary>
        /// <param name="patch">xdelta3 patch data.</param>
        /// <param name="source">The data to be patched.</param>
        /// <returns>Patched data.</returns>
        public static byte[] ApplyPatch(byte[] patch, byte[] source)
        {
            byte[] obuf = new byte[MAX_BUFFER];
            UInt32 obufSize;

            // Call xdelta3 library
            int result = xd3_decode_memory(patch, (UInt32)patch.Length,
                source, (UInt32)source.Length,
                obuf, out obufSize,
                (UInt32)obuf.Length, 0);

            // Check result
            if (result != 0)
            {
                throw new xdelta3Exception(result);
            }

            // Trim the output
            byte[] output = new byte[obufSize];
            Buffer.BlockCopy(obuf, 0, output, 0, (int)obufSize);

            return output;
        }

        #region PInvoke wrappers

        [DllImport("xdelta3.dll", EntryPoint="xd3_encode_memory", CallingConvention=CallingConvention.Cdecl)]
        static extern int xd3_encode_memory (
            byte[] input,
            UInt32 input_size,
            byte[] source,
            UInt32 source_size,
            byte[] output_buffer,
            out UInt32 output_size,
            UInt32 avail_output,
            int    flags);

        [DllImport("xdelta3.dll", EntryPoint="xd3_decode_memory", CallingConvention=CallingConvention.Cdecl)]
        static extern int xd3_decode_memory (
            byte[] input,
            UInt32 input_size,
            byte[] source,
            UInt32 source_size,
            byte[] output_buffer,
            out UInt32 output_size,
            UInt32 avail_output,
            int flags);

        #endregion

    }

    # region Exceptions

    public class xdelta3Exception : Exception
    {
        public int ExceptionCode { get; set; }

        public xdelta3Exception(int rCode)
        {
            this.ExceptionCode = rCode;
        }
    }

    #endregion

Result is an ability to create/patch xdelta3 data in-memory in C# with almost no drawbacks, as we call native C library. No disk I/O, no remote process calls. Only drawback so far is that you have to be careful with MAX_BUFFER variable, not to cause OutOfMemoryException, overflow the C# array or patch data bigger than the buffer’s size. Luckily, I don’t need it for large files, so this implementation serves my purpose.

Xdelta is great open-source binary diff library, you can find more info here: http://xdelta.org