Deploying Dynamics GP Addin Using Visual Studio Menu Item

Deploy Dynamics GP locally using Visual Studio hot key

I demonstrated this technique in one of the sessions I presented on GP development at the 2016 Tampa GPUG conference, but never got around to writing about it.

Often when developing Dynamics GP Addins, you may wish to deploy the current build to your local copy of Dynamics GP, perhaps for testing. This can be done manually but gets old real quick after many iterations.

I set my development environment up by creating a Visual Studio Menu item to deploy the current build of my GP Addin. This means I can simply use a hot key to deploy my code to the application and start debugging within GP or testing.

This solution copies the debug files into the application Addins folder if the build is debug, and removes them if it isn’t.

Follow this guide for what to do, the following screen shot shows the “Deploy GP Addin Locally” option we are aiming to build…

Create the Menu Item in Visual Studio

Visual Studio External Tools Menu Item

Visual Studio lets you add custom Tools to the Tools menu, select “Tools>>External Tools…”, to set this up.

Visual Studio External Tools Window

Use the “Add” Button on the form to create a new entry with the following value:

Title: Deploy GP Addin Locally
Command: powershell.exe
Arguments: -ExecutionPolicy RemoteSigned -File "$(SolutionDir)\Deployment Batch Files\DeployGPLocally.ps1" -BuildOutputFolder $(BinDir)
Use Output window: “Ticked”

Click Apply and OK on the window to preserve your changes.

The "Deploy GP Addin Locally" menu option should now exist on the Tools Menu of Visual Studio but it wont work yet, not without creating the power shell script it calls.

The Menu calls the power shell interpreter (Powershell.exe),  passing the script to run and the build directory to run the script against as command arguments.

The external tools window provides some super handy environment variables you can insert into the fields. Click the little arrow boxes to the right to see the options available, useful for future reference. However in this case we take the output build location for the binary output $(BinDir) and use that folder as the basis for the script to run against. We also use the ${SolutionDir) variable to locate the powershell script, as different developers may have the source in different root directories.

Create the power shell script

Next create the script that is called from the menu item. I have a folder in the solution for this script (Deployment Batch Files), you can hack the location around to your needs changing the path as required.

Save the following into a text file with the name “DeployGPLocally.ps1" in a “Deployment Batch Files” folder located off the root folder of the solution folder for the AddIn Solution.

The script takes the build folder as a parameter, it then looks up the Dynamics GP Application location from the registry, that is then used for the destination of the copied files.

The script decides if visual studio is in a debug or release build mode, by looking for the folder “debug” in the current build path. It then copies the files appropriate to the build type, to the application Addins folder.

DeployGPLocally.ps1

param ($BuildOutputFolder)
 
### SCript to automate deployment of GP Addins to the installed application Addin folder during development
### Written by T. Wappat 2021-11-25
###
###	Todo - check folders exist before operation
### Todo - provide a list of registry locations for various version of GP  ###    https://timwappat.info/post/2016/12/02/Lookup-Dynamics-GP-install-location-from-registry-key
 
# $AddInsPath = "C:\\Program Files (x86)\\Microsoft Dynamics\\GP2015\\AddIns\\"
# Fetch the location of GP application from the registry (this requires that GP installer was used to install it)
$AddInsPath = Get-ItemPropertyValue 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Business Solutions\\Great Plains\\v14.0\\1033\\DEFAULT\\SETUP' 'AppPath'
$AddInsPath = "$($AddinsPath)AddIns\\"
 
# Note the following is regular expression match

if($BuildOutputFolder -match '.\*\\Debug\\.\*' )
{
	Write-Output "Starting to deploy GP (Debug) to $AddInsPath"
	Write-Output "================================================================================================="
	Copy-Item -Path ($BuildOutputFolder + "\\\*.dll") -Destination $AddInsPath -Recurse -Force -Verbose
	Copy-Item -Path ($BuildOutputFolder + "\\\*.pdb") -Destination $AddInsPath -Recurse -Force -Verbose
	Write-Output "================================================================================================="
	Write-Output "Deployed (Debug) GP to $AddInsPath"
}
else
{
	Write-Output "Starting to deploy GP (Release) to $AddInsPath"  Write-Output "================================================================================================="
	Copy-Item -Path ($BuildOutputFolder + "\\\*.dll") -Destination $AddInsPath -Recurse -Force -Verbose
	Get-ChildItem -Path $AddInsPath \*.pdb | foreach { Remove-Item -Path $\_.FullName -Verbose }
	Write-Output "================================================================================================="
	Write-Output "Deployed (Release) GP to $AddInsPath"
}