Here’s the cookbook.
There are three things you need to have for this to work. First is NAV, or better yet C/AL based. Another one is about PowerShell. And the last one, of course, is about Visual Studio.
Let’s go to the NAV end first.
I have a codeunit which registers my controls. Something like this:
This local RegisterControl functions receives all information about control add-ins it needs to register, then it creates (or updates) the Client Add-in record. It also imports the Resource.zip file if you provide a path to one.
So far, so good.
Obviously, what I need to do from Visual Studio when I build my solutions is to invoke this codeunit. How can Visual Studio do that? Simply, through PowerShell. So, let’s take a look at the PowerShell scrip(let) that does that. It’s simpler than you would expect:
Import-Module 'C:\Program Files\Microsoft Dynamics NAV\80\Service\Microsoft.Dynamics.Nav.Management.dll'
Invoke-NAVCodeunit -ServerInstance DynamicsNAV80 -CodeunitId 50001 -MethodName RegisterControls -Argument "C:\Temp"
Yes, it has some hardcoding inside, I could have done it better, but for the sake of the example, it’s good enough.
Now, the last part, the Visual Studio.
In my Visual Studio project properties, I have defined post-build event command lines that do the following:
- Execute VsDevCmd.bat batch file that references the paths to important command-prompt utilities of Visual Studio and .NET
- Delete the Resource.zip file from my project directory
- Call 7z.exe (from 7-Zip product) to zip the content of my Resource directory into the Resource.zip file
- Copy the Resource.zip into a temporary location
- Execute the PowerShell script to register the control add-ins and import the resources
- Clean up any temporary files
- Print the public key token from my output assembly
An example of one of those post-build scripts is this:
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat"
copy "$(TargetPath)" "C:\Program Files (x86)\Microsoft Dynamics NAV\80\RoleTailored Client\Add-ins\CRS" > NUL
md "C:\Temp" > NUL
if exist "%npres%" del "%npres%" > NUL
"$(ProjectDir)Build Tools\7z.exe" a -tzip -r "%npres%" "$(ProjectDir)Resource\*.*" > NUL
copy "%npres%" "C:\Temp" /y > NUL
copy "%npresproxy%" "C:\Temp" /y > NUL
powershell -ExecutionPolicy unrestricted -file "$(ProjectDir)Build Tools\ImportResource.ps1" > NUL
del "C:\Temp\Resource.zip" > NUL
rd "C:\Temp" /Q > NUL
sn -T "$(TargetPath)"
Depending on your installation, it might not just work, maybe you’d need to fix some paths. Also, you must include this PowerShell script, as well as 7z.exe in your project. I typically have a folder called Build Tools where I put all the necessary dependencies for the build process.
And that’s all.
Now, this is not the best way, of course, to do this. A much better way would be to develop build tasks, and create a Visual Studio plugin that handles all this, but just call me too lazy to do that. This simple script gets the job done for me, and if it does the same for you, all the better.
Good luck, and let me know what you think of it. It’s okay to say “this sucks”