I was asked this question today
Do I need to restart IIS (Internet Information Services) after I have deployed my plugin?
My initial quick answer was no but then I was curious why they asked me the question? This is what I refer to as a suspicious question. Often the question people ask, isn’t the real question they want to ask, a bit like when my 3 year old daughter asks.
“What’s that chocolate bar doing on the table Daddy?”
The real question
“Daddy I want to open and eat that delicious looking chocolate bar”
This picture isn’t my child but it’s a fits the text above
Plugin storage options
There are three plugin storage options
The options are fairly self explanatory. (plugin.dll is your custom plugin assm)
- Database = Plugin.dll uploaded into the database
- Disk = The Plugin.dll is saved on the CRM Servers hard disk
- GAC = The plugin.dll is loaded into the GAC on the CRM Server.
If you don’t know what the GAC is it’s the Global Assembly Cache. It’s a common area on a computer to store the DLL’s which is C:\Windows\assembly. This discussion has a good definition – What is the GAC in .NET
As always Start with the SDK, which has a good article on the subject
The default option should be store your plugin on the database and to be honest I can’t think of any reason why you would store you plugin not in the database. Microsoft STRONGLY agrees with me (excellent, I like it when Microsoft does that)
We strongly recommend that you store your production-ready plug-ins in the Microsoft Dynamics CRM database, instead of on-disk.
The advantages of deploying your plugin to the database our
- The plugin is backed up when the database is backed up
- For multiple server configurations you only need to deploy once to the database and not individually to each CRM server.
- Plugins in the database can be added to solutions, Disk, GAC plugins cannot
- Plugins deployed to the GAC or Disk will need an IISRESET to refresh, plugins deployed in the database do not.
- Sandboxed and CRM Online plugins have to be deployed in the database
If you want to understand what deploying to the Sandbox is read my blog post Understanding Plugin sandbox mode
I have experienced a CRM deployment where common code used by the plugins was held in a separate DLL which was stored in the GAC of the CRM servers. The preproduction environment had 8 CRM Servers and the Production environment had 11 CRM servers. It was a tedious job to install the DLL on every server, restart the ISS server and CRM async services.
I cannot think of any advantages to installing CRM plugins on the server or in the GAC so my advice is never to do it.
Some people might think you need to install the plugin.dll on the CRM server to enable remote debugging but this isn’t true, you can install the plugin.dll in the database and put the pbd file in the the folder C:\Program Files\Microsoft Dynamics CRM\Server\bin\assembly. Microsoft gives you this tip on the Debug a plugin page
It is possible to debug a database deployed plug-in. The compiled plug-in assembly’s symbol file (.pdb) must be copied to the server’s <crm-root>\Server\bin\assembly folder and Internet Information Services (IIS) must then be restarted. After debugging has been completed, you must remove the symbol file and reset IIS to prevent the process that was executing the plug-in from consuming additional memory.
Personally I prefer to use the plugin registration tool to debug plugins because this can be done a CRM Developers individual machine. When people remote debug on the CRM server this can sometimes slow, stop the CRM Async services from running and processing other plugins.
Basically it’s not good CRM developer etiquette to stop other developers using the system because you need to debug a plugin (although sometimes need must).
A better system is to write unit tests to test the logic of your code in isolation
- Why CRM Developers should unit test their code
- Experiences of Unit testing with Microsoft Dynamics CRM Projects
- Information to Get started with Unit Testing with Microsoft Fakes and Microsoft Dynamics CRM 2013
CRM MVP Gonzalo Ruiz has written a great article on the benefits of registering your plugin to the CRM database.
6 Great Reasons to Register your Plugins in Database Instead of Disk/GAC
Point number 4 is interesting
4. Disk assemblies will not support multiple versions
I never realised (or yet needed/wanted to use) you can store multiple versions of an assembly.
I found one small reason for deploying to disk, highlight by this blog by David Jennaway, where he mentions if you plugins have dependant dll’s you can put them in the same directory as the plugin, in a similar way the plugin registration tool has the CRM SDK dll’s in the same directory but this isn’t much of a reason.
What can you restart and how does it effect plugins
There are a few things which you can restart which can affect your CRM plugins. I will state plugins deployed to the CRM database do not need any of these restarted, which is another good reason to deploy your plugins to the CRM database.
- IIS Server
- Recycle CRM App pool
- Restart CRM Services
You do sometimes need to check the IIS Server or CRM services if your CRM isn’t working, for more detail check out the article Microsoft Dynamics CRM not working? check these common causes
Lots of CRM developers I have met do an IIS Reset and Async CRM Services restart when ever they deploy a plugin, even when the plugin is deployed in the database and they didn’t need to. The reason they did this was because the CRM developer who helped them learn CRM did it, so now they do it.
First lets understand what doing an IIS Reset does. When you type IISRESET into the cmd line or go to the IIS server and click restart. The first thing you should do is warn the users you are about to take down CRM and all other websites and web services hosted in IIS. The key point is it restarts everything on the IIS server and not just CRM, make sure you want to restart everything.
IISRESET restarts these services, it’s the same as stopping and then starting the three services below according to this post
- IIS Admin Service
- Windows Process Activation
- World Wide Web Publishing
This discussion has an excellent summary what IISReset does What does an IISReset do?
IISReset stops and restarts the entire web server (including non-ASP.NET apps)
Recycling an app pool will only affect applications running in that app pool.
Editing the web.config in a web application only affects that web application (recycles just that app).
Editing the machine.config on the machine will recycle all app pools running.
IIS will monitor the /bin directory of your application. Whenever a change is detected in those dlls, it will recycle the app and re-load those new dlls. It also monitors the web.config & machine.config in the same way and performs the same action for the applicable apps.
useful tip – If you are doing an IISReset via command line then it’s a good to do
This will gracefully close down IIS rather than IISReset and wait for processes to finish. IISReset will abruptly close down IIS which could leave processes half way through updating the CRM database! which is something you want to avoid.
This discussion highlights an area where you need to recycle the app pool
Do we really need IIS Reset and Async Services restart when we depoly plug-in or custom workflow – CRM 2011
There is one other scenario where you need to recycle the CrmAppPool application pool. If you modify the parameters that are available for a Custom Workflow Activity, then CRM will not make any new parameters available when editing the workflow until after recycling the application pool.
Recycling the CRM app pool is a lot less disruptive than restarting the whole server.
I couldn’t find any need to do an IIS reset for database stored plugins, I think you would need to recycle the app pools to if you your plugins are stored in the GAC or Disk.
You have a number of choices when deploying plugins which effects what CRM process runs the plugin code. Here are the CRM services
If you choose Sandboxed the plugin code will be run in CRM Sandboxed Processing services, this service is sandboxed, if the plugin tries to modify or access external dll’s, certain system resources an error will be thrown.
if you choose none it gets run by the core CRM system in the event execution pipeline if it Synchronous, if it’s asynchronous it gets run by the CRM async service
CRM Async services
I have written before about CRM 2013 – Understanding SystemJobs and Async Plugins.
If you look at the msdn article – Event execution pipeline, this picture shows you the various parts of CRM
Synchronus plugins runs straight away and the CRM form will hang until the plugin has successfully run. Looking at the architecture above you can see synchronus plugins get run in by the core CRM system inside the database transaction.
Async Plugins get run after the Plugin execution pipeline has finished and go into the Async Queue Manager and get run when CRM has free resources. Researching this topic today I found Microsoft has quite a large section on Asynchronous services in CRM, which I have never read until today
Asynchronous service in Microsoft Dynamics CRM
This article Asynchronous service architecture is mentions this
The asynchronous service features a managed queue for the execution of asynchronous registered plug-ins, workflows, and operations such as bulk mail, bulk import, and campaign activity propagation. These operations are registered with the asynchronous service and executed periodically when the service processes its queue. The asynchronous service can be hosted on a server other that the server running Microsoft Dynamics CRM.
The reason I mention the Async service is because there is a small piece of best practise I had not considered or heard before tucked in the
You should stop the asynchronous service before you unregister a plug-in that was registered to execute asynchronously. Stopping the service prevents a situation where an asynchronous registered plug-in has been queued for execution but for which there is no plug-in assembly currently registered. For example, consider the situation in which a plug-in has been registered to execute asynchronously and the related event has fired. After the asynchronous operation has been queued by the queue manager, you then unregister (delete) the plug-in assembly from the Microsoft Dynamics CRM database. In this case, an error occurs when the asynchronous service tries to execute the queued asynchronous operation but the plug-in assembly no longer exists.
So if you have Async plugins then it’s good practise to restart the CRM Async service when you unregistered an async plugin. This will avoid a plugin being queued which has been unregistered.
Finally I will leave you with the my post on common plugin errors and isolation mode
CRM 2011/2013 – Common Plugin Errors and Isolation Mode
Back to the question
I forgot about the question. The answer is no the developer won’t have to do an IISReset if the plugins are deployed to the database, which they were.
It’s been interesting researching this topic and I have learnt a bit more about the CRM architecture
Great article – one thing I didn’t see mentioned is the Plugin/Workflow Assembly Version. If you increment the version each time you build, CRM will automatically clear its internal cache on all servers and start using the new version immediately without resorting to any sort of IISRESET. This is how it is possible to work with custom assemblies in the CRM Online version since you don’t have access to IIS or the server. It works great for on-premises too!
Hi Josh, thanks for the comment and interesting link, it’s a good addition to the article.
I could have added more things to the blog post but the post was already on the large side and I ran out of time (and concentration on this topic)
Nice article. Our team has found that you cannot necessarily deploy via the DBMS option if your plugin depends on other custom DLLs. Yes, the ILMerge tool can be used to merge the various DLLs into one and you can deploy *that* to the DBMS, but works only to a point. After a certain size (say 15 MB) the resulting DLL becomes slow to load and has a noticeable affect on performance. We have found that it’s best to endure the configuration headache and deploy via the GAC when that threshold is reached.
Great article – I am just wondering, if I register a plugin in the database, where does the code actually run? On the SQL server or on the CRM server using the async service? (I only have the 2 servers where my CRM server acts as both the ‘front end’ and ‘back end’ roles).
The reason I ask is that I have a CRM plugin which among other things, communicates with an SMTP server to send an email, so I need to set firewall rules from the server the code is running on to be able to access the SMTP server.
nice article! thanks.