Notify applications post-install

This PR replaces the `IAppUpdate` framework with a much simpler scheme, that is also compatible with native C/C++ applications. Closes #14.

## Spec

After applying updates, Squirrel will scan the new installation directory for EXEs which match one of these two characteristics:

* The EXE is a .NET assembly and it has an AssemblyMetadata key of "SquirrelAwareVersion" with a value of "1"
* In the English-language block of its PE Version header, it has a key of "SquirrelAwareVersion" with a value of "1"

Every EXE that is found that matches will be invoked with:

* `/squirrel-installed [new-version]` - Invoked on initial install
* `/squirrel-updated [new-version]` - Invoked whenever the EXE is updated
* `/squirrel-uninstall [version]` - Invoked when the application is fully uninstalled

You **must** exit as soon as possible once you finish the post-installation operations.

Once installation is complete, if this is the initial install, all Squirrel-aware EXEs will be invoked with:

`/squirrel-firstrun`

If this is your main application, you should probably just ignore this and execute. If this is a utility application solely dedicated to Squirrel or you don't want it to show up once the initial install completes, just exit.

## TODO

- [x] Write code to detect EXEs that match and generate a list from an app install directory
- [x] Wire this up to the install / apply / uninstall code
- [x] Invoke first run
- [x] Write tests to verify
It is async, but since InvokeProcessAsync already returns `Task`, we don't have to write the extra await - it'd be like writing:

```cs
async Task SomeMethod()
{
    await SomeOtherThingThatReturnsTask();
}
```

When we could just write:

```cs
Task SomeMethod()
{
    return SomeOtherThingThatReturnsTask();
}
```