Friday 1 November 2019

Plugin Registration tool - it's nuget shiny new but the update button doesn't work?

You've downloaded the package, unzipped it and it runs just fine... or does it!

The update button doesn't work :(

The issue is that windows has handily blocked access to the dlls the registration tool calls.

The fix is to right click each file in turn and unblock them... or you can run this nifty command in powershell and save yourself from a nasty dose of RSI.

1. Run PowerShell as an Administrator
2. Run the following command but update the path to the folder were you unzipped the tool:

get-childitem "C:\Software\Dynamics 365 Plugin Registration" | unblock-file

3. Have a pint, you've earned it :)

Thursday 31 October 2019

Hyper-V Backup Script...

Slightly off topic but still very relevant when developing Dynamics 365 solutions. Typically that developer sandpit we're working hard on is running in Hyper-V and whilst we're using source control to back up our work, backing up your VMs is just as important.

Here's a nifty Powershell script for Windows 10 that for each Hyper-V Virtual Machine will:

1. Save the state of the VM if it's running
2. Robocopy the VM including snapshots to a backup drive
3. Restart the VM if it was running

# ----------------------------------------------------------
# HYPER-V BACKUP SCRIPT
# ----------------------------------------------------------

$Date = Get-Date -format yyyyMMdd

# Backup HyperV
$VMs = Get-VM * | Select Name,State,Path

foreach ($VM in [array] $VMs)
{
$VmName = $VM.Name
$FolderPath = $VM.Path
$InitialState = $VM.State

"Backing up Virtual Machine: " + $VmName + " - " + $FolderPath + " - " + $InitialState

if ($InitialState -eq "Running")
{
"Saving VM........"
Save-VM $VmName
"Done!"
}

$BackupPath = "Z:\HyperV\" + $VmName

"Starting backup...."
# 4. Backup VM
Robocopy $FolderPath $BackupPath /e /mir /np /tee /mt /log+:"Z:\Logs\"$Date"_"$VmName"_Backup_Log.txt" #/XD *.vhdx
"Backup complete!"

# 5. Restart VM
if ($InitialState -eq "Running")
{
"Re-starting VM........"
Start-VM $VmName
"Done!"
}
}

Monday 14 October 2019

Getting a D365 Record ID via Bookmark

This is a nifty trick for getting the ID of a record in D365:

1. Create a new bookmark with the following as the page:

javascript: if (window.prompt("CRM Record GUID is :", $("iframe").filter(function () { return ($(this).css("visibility") == "visible") })[0].contentWindow.Xrm.Page.data.entity.getId().slice(1, -1))) { }

2. Navigate to the record you require in D365.

3. Hit the bookmark.

Saturday 17 August 2019

Adding support for a Swagger REST API in a Dynamics Plugin

So recently I've been working on consuming a Swagger REST API in a Sandboxed plugin.

Visual Studio now includes some nice features to support this such as the ability to automatically generate an API Client and the models used by an API directly using Swagger.
You simply right click > add > REST API Client and then enter the url to the Swagger documentation (EG. http://api.yourapi.com/swagger/docs/v1).
Visual Studio generates all the classes for you.

So far so good... :)

However, before you skip happily off into the sunset there are a couple of gotchas....

1. The APIClient classes generated cannot be consumed from a Sandbox plugin - they cause security exceptions as they reference libraries not supported by plugins running in isolation mode. If you are running on prem outside the Sandbox you're good to go - if not... you'll need to call the API directly using HttpClient instead.

            var content = new StringContent(json);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            HttpClient client = new HttpClient();
            HttpResponseMessage resp = await client.PostAsync($"{apiUrl}api/dostuff", content);
            return resp;

2. If your Plugin consumes other libraries using ILMerge and you also reference NewtonSoft you may hit issues. This is because at the point you generate the REST API classes a nuget package reference is added to your project. In my case I already had a reference to NewtonSoft version 12. The REST API package references version 6. This works fine - the version difference is handled and the classes are generated correctly. However, when I attempt to compile after the operation has completed, ILMerge barfs and the build fails.
The fix is to delete the nuget package and recompile. Everything works again... but you've lost a couple of hours of life and that right click, add REST API Client has lost some of it's sparkle ;)

Thursday 2 May 2019