As people dive into customizing GP they move through various stages, making a field required (modifier), report designer, VBA extended windows & reports (cringe), eConnect & SQL scripting, VST .NET AddIn, and the holy grail...DEX. Out of all of these probably my favorite, and hopefully yours too, is .NET AddIns. They provide a good level of integration with GP and give you a solid foundation of C# that makes it exponentially easier to create, understand, and maintain. Having a strong background with C#, my preferences are clear.
Our company works in a fast paced environment with right at 100 GP users, we are continuously changing and evolving. One of the headaches with any of the customization methods from above is generally updating them. Our environment consists of a farm of terminal services that users remote into to access GP, but even if you have local installations of GP you still need to touch every single machine. More pointedly, everyone has to be out of the system. In a world where people start getting in at 6AM and stragglers may stay into till around 10PM (at month end, all bets are off). It makes it difficult to find a time that doesn't burden our users and still allows me to get some sleep. This becomes even more of an issue when you may have 2 or 3 enhancements or changes per week, that's a a lot of late nights cursing the users that burn the midnight oil. So I went about fixing that.
There are two technical hurdles that necessitate updating GP AddIns while no one is in the system.
- Dynamics GP locks the files in the AddIn folder so that once it is has loaded a DLL, you can not overwrite it until all GP clients that loaded the files are closed.
- A lot of the code in VST AddIns is driven off events, for example window RMTransactionInquiry opened, while it is super easy to register to receive these events, there is no way to get unregistered, so once something has registered, it remains registered for the lifetime of that GP client.
These two hurdles are the main challenges I had to overcome, the solution using a Shim. First a little background on VST AddIns and how GP loads them. Essentially you create a library that contains one or more classes that implement IDexterityAddIn, when a GP client starts running it loads all of the DLLs in the AddIn folder and scans through the libraries for these implementations of IDexterityAddIn. Once it finds them it creates an instance and invokes the Initialize method. Simple enough. So how are we going to go about Shimming this AddIn process? The easiest solution would be to have a very small IDexterityAddIn that looks on the network for your real DLL files and then loads them dynamically. This would certainly make things easier, GP clients would grab the latest version of our AddIns whenever they opened GP and we could update the AddIn DLL files on the network as often as we want.
The code above would be compiled and placed in the AddIn folders of all your GP clients, then when GP is opened the initialize method will be called and that's where the Shim's magic comes in. The Shim simply looks at some network folder and finds all of the DLLs in that folder, uses reflection to load and instantiate all of the implementations of IDexterityAddIn and then finally calls the Initialize method on each of the AddIn. So with this Shim in place I can push out updates as often as I like and user's will simply use the latest version of my AddIn every time they open a GP client.
Welcome to the Dynamics GP User Group [GPUG], we’re so glad you’re here! While we realize you may be here to troubleshoot a technical issue or simply learn new tips and tricks, we’d love the chance to share with you the incredible benefits the User Group has to offer [and don’t forget, if you’re interested in an incredible in-person learning opportunity - join us in Nashville for our Summit event]!