Search This Blog

Tuesday, November 17, 2009

Tools Update : New connection control

Hi everybody,

Following a user request, I added a new connection control in all my tools, which allows to save and load connections configuration from/to a configuration file. This file is used by all the tools.

Here is the connection control


The password request form (as passwords are not stored in the configuration file)


And actually, the form which allows to select one of the existing connections configuration. It is used when an action requires an active connection to a CRM Server.


In order to help you to download all updated tools, I created an archive containing all tools.

Thursday, November 5, 2009

Who customize what and when?

The customization feature of Microsoft Dynamics CRM 4.0 is well known for being one of its best strengths. However, it lacks one essential feature nearly: The monitoring of theses customizations.

Indeed, it is impossible to know who does what in terms of customization and above what customizations were published.

With plugins and the famous capabilities of customization, it is relatively simple to set up an event log of customizations in Microsoft Dynamics CRM 4.0.

What you need is Plugins and one Custom Entity (let say “Customization Log”)


Microsoft Dynamics CRM 4.0 provides us with several messages that allow us to track what is happening in terms of customizations the application.

There are two types of messages:

  • Import Messages
  • Publish Messages

Import Messages

They can give you two pieces of information:

  • The customization file that was imported (CompressedCustomizationXml property)
  • The entities or parameters that have been imported (ParameterXml property)

The messages are:

  • ImportCompressedAll
  • ImportCompressedWithProgress
  • ImportAll
  • Import
  • ImportWithProgress

Catch all these messages to be sure to monitor every import event.

In the case of imports, you can retrieve the customization file in the incoming properties (CompressedCustomizationXml) of the plugin context. So you can get the customization file during PRE stage (context.Stage == 10).

Publish Messages

They provide us with the list of entities that have been published (through the property ParameterXml of the plugin context).

The messages are:

  • PublishAll
  • Publish

Knowing this information, it is possible to export published entities customizations.

In the publish case, we only know the names of entities that are published. So, we must therefore export customization during POST stage to retrieve the customization file for the published items.

The plugin Process

In both cases (Import and Publish), we saw that we have the list of imported/published entities and the associated customization file.

So, our plugin has only one thing to do: create a record of "Log customizations" entity type that will contain the following information:

  • The type of operation: Import or Publish (which can be displayed as a picklist)
  • Entities involved stored in a memo field (because you can potentially have many imported/ published entities - Beware the maximum field size, therefore)
  • The customization file as an attachment

To make all this easier to use, we will take care of:

  • Bringing the notes section on the form first tab
  • Displaying the columns “type of operation”, “Actor”, “transaction date” and “entities involved” in the "Active Customization Logs” view.

Here it is! You have a monitoring feature for your customization !

BE AWARE of handling all exceptions because your imports will not work anymore if the plugin throw an exception

NOTE : To compare two customization files and know what have been updated, you can use the CRM Customization Comparison Utility provided by Microsoft on the CRM Team Blog

Custom web application and bin folder... Yes, but...

As you can see on the Best Practice of the CRM SDK (, since rollup 2, you can put your custom assembly to your own web application bin folder instead of using the bin folder of the CRM web application.

Since a while, I didn't understand why this practice seemed to work for everybody except me...

The answer is simple: The assembly name can't contain any dot if you want it to work... It is a known bug by Microsoft.

As I was used to name my assemblies like .Crm.Web, it couldn't work...

I hope this will help some of you, guys!

Wednesday, October 14, 2009

Update : Form Javascript Manager

Today, I updated the form javascript manager with minor features

Change log:

  • When scripts are exported, you can now move to the Import tab automatically
  • Scripts are updated automatically in the tool when the files on disk are updated
  • It is now possible to import AND publish scripts in one action (you don't have to click on Import then on Publish)
  • You can Import/Publish using contextual menu or button
  • Encoding is better managed for non english language

As usual you can download the last version following this link

Monday, October 5, 2009

Important Update : View Layout Replicator


This post to warn you about the existing version of ViewLayoutReplicator.

You can experience troubles with your lookup fields when browsing for records if you have replicated a public view to the search view of the lookup related entity.

The behavior is the following:

When selecting a record from the search window, the lookup field just contains the icon of the entity and not the primary attribute as the result of the selection. This is due to the "preview" attribute of the search view that should be "0" (and not "1" which happens if you used the ViewLayoutReplicator as described above).

To correct this behavior, simply download the new version of the tool and replicate the view again.

Thursday, October 1, 2009

New tool: XML Validator


Today, a really small tool that helps to find error in CRM customization file. It is so boring to get the standard error message from the import customization page when your customization file is broken...

Of course, you can download and install tools like XMLSpy but it has too many funtions for me. So, I wrote a small tool that allows you to validate a XML file with a XSD file. It is generic and works also for other XML files than CRM one.

On the downloadable file, you will find the program and a XSD file which groups the three CRM XSD file used for the customizations (ExportImport, ISV.config and SiteMap).

You can select files (XML and XSD) by browsing the computer or by drag and drop.

I hope that will help some people, enjoy!


Tuesday, September 22, 2009

SiteMap, IFD/OnPremise and relative URLs

I don’t know if you've already faced this problem: When you develop a web page that you want displayed via the SiteMap Navigation, the URLs called are different depending whether you are in OnPremise or IFD mode.

In IFD, you get a URL like http://organization_name.domain.extension/ISV/default.aspx

In OnPremise, it will look like

I assume that you use the same URL to access both Dynamics CRM authentication mode.

Now, if you want to use relative URLs to load images, scripts or other (which are also contained in the ISV folder), you're facing a problem: how to use relative URLs to be valid for both IFD and OnPremise mode?

The simplest answer, which is often found on the forums, is: Use absolute URLs.

Certainly, but this is not very clean to use hard coded server names.

So I propose you my method. Maybe not the best but it does the job (even if, as we shall see, it still uses absolute URL).

In the code behind your ASP.Net page, create a new string property called BaseUrl.

In the Get accessor, write the following code:

public string BaseUrl
string baseUrl = string.Format("{0}://{1}",
Request.IsSecureConnection ? "https" : "http",

return baseUrl;

Then in the HTML content of your website, you can use the <% = BaseUrl %>wherever you want to reference relative URLs.

For example:

<img src="<%= BaseUrl %>/ISV/MyImages/Image.gif" > 

Well, it’s right, you still have an absolute URL in the source code of the page. But at least you do not have to worry about changing environments and authentication mode.

Note: If you need relative URLs on your scripts, you can replace the ".js" file by an ".aspx" file and perform the same manipulation as above.

Monday, September 21, 2009

Tools Update : IFD authentication supported

Hi all,

It's been a while since the last post... Unfortunately (or not, related to current economic context), I have lot of work these days and it's quite difficult to find time for my blog.

But nevertheless, I found time to update authentication process in my tools and they now all support IFD authentication.

The little extra concerns ViewLayoutReplicator and SearchablePropertyAttributeUpdater tools: they now use the same authentication assistant than the others tools.

You can still download them using right panel of this blog


Thursday, July 30, 2009

Tools update : Secure connection added

As you might have noticed, my tools didn't support SSL when establishing connection with CRM Server...

It is now corrected! All tools can access crm website using https

The next update will be to enable IFD authentication... Stay tuned!

NB: I put all download links on the right pane of this blog

Monday, July 27, 2009

New tool! Bulk Delete Launcher

Today, a new tool that allows you to run bulk deletion of records. Indeed, this feature of CRM is not accessible through the user interface but only with SDK.

To use this tool, you must first create a view in the advanced search that will find the items you want to delete.

Then just run the tool, to indicate on which entity (using the logical name of the entity) is the view advanced search and set scheduling options and recurrence (if desired).

You can also request to receive an email from the CRM server when processing is complete. This option is available if the user account you use has an email address saved in the user profile CRM.



Thursday, July 9, 2009

Workflow: Add rich HTML content in email body

One of the limitations of workflow in Microsoft Dynamics CRM 4.0 is the uncapability to add dynamic HTML content. By dynamic, I mean with data from the item that triggered the workflow.

We all know the trick of copy/paste to add static HTML in the mail but to add dynamic content is a different kettle of fish ...

In particular, I think about the following needs:
  • Display a table containing the information related to the current record (eg list of contacts from an account)
  • Show a link to a form without displaying any url but just a clickable word
Note that it is possible to manage these cases with custom workflow activities. In fact, when you insert a workflow output text in an email, the content is not encoded, ie you can pass HTML tags that will be interpreted as such.

For example:

<a href="aLink">Click here</a>

will just display

Click here

In the same way, you can display HTML table with CRM content and insert it in mail body.

[UPDATE] Code example - Url builder. This code create an hypertext html control that will be used in email body. You can set a text for the hypertext control with the input property and you get back the hypertext control in output property

   1: public class EntityUrlHelper : SequenceActivity
   2: {
   3:     public static DependencyProperty linkProperty = DependencyProperty.Register("link", typeof(string), typeof(EntityUrlHelper));
   5:     [CrmOutput("Link")] public string link
   6:     { 
   7:         get 
   8:         { 
   9:             return (string)base.GetValue(linkProperty); 
  10:         } 
  11:         set 
  12:         { 
  13:             base.SetValue(linkProperty, value); 
  14:         }
  15:     }
  16:     public static DependencyProperty textLinkProperty = DependencyProperty.Register("textLink", typeof(string), typeof(EntityUrlHelper));
  18:     [CrmInput("Hypertext link text")]
  19:     public string textLink
  20:     { 
  21:         get 
  22:         { 
  23:             return (string)base.GetValue(textLinkProperty); 
  24:         } 
  25:         set 
  26:         { 
  27:             base.SetValue(textLinkProperty, value); 
  28:         }
  29:     }
  31:     protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
  32:     { 
  33:         IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService)); 
  34:         IWorkflowContext context = contextService.Context;
  36:         link = "<a href='http://someUrl/page.aspx?id=" + context.PrimaryEntityId.ToString() + "'>" + textLink + "</a>";
  37:         return ActivityExecutionStatus.Closed;
  38:     }
  39: }

Tuesday, July 7, 2009

Plugins and update record state: Do I have to use message SetState or SetStateDynamicEntity

One question that came to me while I had to develop a plugin when record state changed...

The answer is quite simple if you understand how the CRM application communicates between the presentation layer and data access layer. In fact, all communications between the forms and the data access layer seem to be in the form of DynamicEntity.

So when you change the status of a record via the forms, or when you use the SDK class SetStateDynamicEntityRequest, you register your plugin on the SetStateDynamicEntity message .

If you use in your code SetStateAccountRequest class (for example), you must register your plugin on the SetStage message.

Friday, June 5, 2009

Add an information message in CRM form

With the following script, you can add an information message to a CRM form

var newcontent = document.createElement("div"); = "message"; = "solid 1px black"; = "10px"; =
"10px"; = "0px"; = "4px";
newcontent.innerHTML =
"<table border="'0'" cellspacing="'0'"
src="'/ico/16_info.gif'/" /></td><td
is an information

var scr = document.getElementById(elementId);
scr.insertBefore(newcontent, scr.firstChild);

Juste replace elementId with:
"areaForm" to place the message on top of tabs
"tabX" to place the message in the tab X (X is the index of the tab)

Si had put a easier and more integrated solution in the comments. So I put his solution right here to avoid further navigation. Thank you, Si!
Nice, just used this but you can see from the screen shot that inserting
the div as the first child of areaFrom makes the bottom of the form disappear,
you can't see the bottom of the scoll bar is not visible.
I've checked the form dom and there's a nice div called Navigation that is
already styled with a yellow backgroundHere's your code altered slightly that
allows CRM to format the screen correctly, it can also be called multiple times
and will update the text.

var sText = 'Hello World!';
var elementId = 'Notifications';
var id = 'divMessage';
var src = document.getElementById(elementId);
var newcontent = document.createElement("span"); = id;
newcontent.innerHTML = "<table><tbody><tr><td><img src="/_imgs/ico/16_info.gif" /></td><td valign="'top'">" + sText +
"</td></tr></tbody></table>"; = "";
var previous = src.firstChild;
if (previous == null previous.attributes['id'].nodeValue != id)
if (src.childNodes.length == 0)
elsesrc.insertBefore(newcontent, src.firstChild);
src.replaceChild(newcontent, previous);

Thursday, June 4, 2009

New tool! Header Builder


I developed a new tool, a small one this time.

It simply allows you to create a new header for Microsoft Dynamics CRM 4.0 application.

Some customers don't want to highlight the name and logo of the solution and prefer to put their own company logo instead.

With this tool, you can choose an image and merge it with the header background of Microsoft Dynamics CRM 4.0.

The programm manages transparency, size and position of the image on the header background.

You can then save the new header iamge and replace the original one located in CRMWeb\_imgs\masthead.jpg (don't foget that it is unsupported and you must backup the original file)

No screenshot for the moment


Wednesday, May 27, 2009

If you like Dynamics CRM Tools...


A friend told me about the possibilities of donations through PayPal. I therefore put in place a donation on my blog.

If you like the tools I developed, that you consider they are worth something and you want to support me, you can make a small donation using the button below or the right menu

Thanks to every people using my tools!

Monday, May 25, 2009

Update of Form Javascript Manager (v1.2)


Just a minor update of the program following feedback about a bug where a new onSave event overwrites an existing onload event.


Tuesday, March 31, 2009

1000 visits

Already 1000 visits!

Thank you all for your interest in this blog.

There won't be a lot of posts in coming days, I need to prepare my wedding to be held in a month now

Friday, March 20, 2009

New tool! Isv.config Manager

Hello everyone

Today, I propose a tool that asked me a lot of time to write but I am quite happy about it. It allows you to change the ISV configuration through an interface (unlike the tool CrmXmlEdit you probably know). So, you do not have to remind XML nodes and attributes for each element.

Some features:

  • Creation / Editing / Saving a configuration ISV
  • Export / Import configuration ISV from CRM server
  • Edition by mouse clicks
  • Url test with web pages and icons preview
  • Validating the ISV configuration using the XSD provided by Microsoft

Some screenshots:


As usual, I remain attentive to the requests for modifications or lift bug (yeah, I know it could happen)

[UPDATE] I forgot the Icon element for MenuItem, it's now corrected...

[UPDATE 2] Thanks to the anonymous guy, a bug was corrected regarding connection status when loading entities name for entity element. You can download the corrected version.

Tuesday, March 17, 2009

New version of Form JavaScript Manager (v1.1)

I had some feedback on this tool and then, here is a new version.
It is now possible to export several entities at the same time, by selecting from a list or by manually writing.
Bug fixes:
It could happen that the form event scripts are inverted if already exist in the form. Thus, a script could go onSave in the onLoad.


Tuesday, March 3, 2009

New tool: JavaScript Form Manager

After a few days (weeks?) of silence, I am pleased to offer you my latest tool: JavaScript Form Manager.

What does this tool?
  • Export of form JavaScript (onload, onSave, onchange) in JavaScript file on disk
  • Preview of scripts
  • Edit scripts (ie launching the default text editor or Visual Studio)
  • Import scripts from JavaScript files to the form and publish entities

Supported input file name:

  • entityName-onloadORonsave[-anythingElse].js
  • entityName-onchange-attributeName[-anythingElse].js
Examples: account-onload.js / onload-account-test.js / account-onchange-name.js / account-name-onchange-anotherTest.js

This tool allows you to avoid navigating in the forms to test and manage your scripts. You do now everything from the tool, in a graphical way.



As usual, feel free to give me feedback if you encounter problems or if you think that this program can be improved

Friday, February 13, 2009

New version of Rollup 2

A new version of the rollup 2 for Microsoft Dynamics CRM 4.0 has been released, it corrects some errors about string localization and custom web.Config.

you can download it here

French blog for french people

I just opened a blog in french, just to post the same articles as in this blog, but in french.

the link :

Monday, February 9, 2009

Unable to publish workflows after having installed Rollup

I got the following problem after rollup installation: I couldn't publish my workflow anymore...

The answer came from a Dynamics CRM Forum post:

Open web.Config file of CRM website and add the following line to the authorizedTypes Xml node:

<authorizedtype authorized="True" typename="CultureInfo" namespace="System.Globalization" assembly="mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089">

Do an IISReset

The publication should work!

Tuesday, January 20, 2009

New Tool ! View Layout Replicator

I announced this tool almost two months now and I'm proud to release it: the view layout replicator!

This tool will save you lot of time (except if you like updating Xml by hand, anyway): You can desing only one view for an entity and then, use this tool to replicate the modifications to the other views.

For example, we all customize "All active accounts" for our customer but how many do the same with all others public views and Quick Find, Advanced Find, Related View,etc?

With this tool, you can replicate any view to any view except one product restrictions: There can't be associted entity column in a related view.


Friday, January 16, 2009

MSCRM 4.0 update rollup 2

A new rollup is now available on Microsoft Download site.

It seems to correct our bugs that appeared with rollup 1. Don't need to install rollup 1 before, if you didn't.


Wednesday, January 7, 2009

JScript : know which action raised onSave event on form


I didn't have noticed a useful property for the onSave() method in crm Forms, I talk about the property "event.Mode".

This property lets you know for which reason the onSave() method has been called:

Here is the list of event:
  • None : 0
  • Save : 1
  • SaveAndClose : 2
  • Delete : 3
  • Load : 4
  • Deactivate : 5
  • Reactivate : 6
  • Email Send : 7
  • Email Reply : 8
  • Email Forward : 9
  • Kb Submit : 10
  • Kb Reject : 11
  • Kb Publish : 12
  • Kb UnPublish : 13
  • Kb Rate : 14
  • Lead Unqualify : 15
  • Lead Qualify : 16
  • Quote Accept : 17
  • Quote CreateOrder : 18
  • Order ProcessOrder : 19
  • Opportunity AddRelatedOrder : 21
  • Opportunity AddRelatedQuote : 22
  • Opportunity AddRelatedInvoice : 23
  • Quote CreateRevision : 24
  • Quote CloseQuote : 25
  • Order CancelOrder : 26
  • Invoice Close : 27
  • Quote GetProducts : 28
  • Quote Activate : 29
  • Email ReplyAll : 30
  • Contract Hold : 31
  • Contract ReleaseHold : 32
  • Contract Cancel : 33
  • Contract Renew : 34
  • Product ConvertToKit : 35
  • Product ConvertFromKit : 36
  • ContractDetail Cancel : 37
  • Contract Invoice : 38
  • Contract Clone : 39
  • Incident Cancel : 40
  • Email Assign : 41
  • Change SalesStage : 42
  • SalesOrder GetProducts : 43
  • InvoiceGetProducts : 44
  • TemplateMakeOrgAvailable : 45
  • TemplateMakeOrgUnavailable : 46
  • Assign : 47
  • IncidentAssignToUser : 49
  • OrderLock : 50
  • OrderUnlock : 51
  • InvoiceLock : 52
  • InvoiceUnlock : 53
  • ConvertResponse : 54
  • ReportMakeOrgAvailable : 60
  • ReportMakeOrgUnavailable : 61
  • WorkflowAddCheckStep : 62
  • WorkflowUpdateCondition : 63
  • WorkflowCreateAction : 64
  • SendInvite : 65
  • WorkflowAddElseIfStep : 66
  • WorkflowAddElseStep : 67
  • WorkflowDeleteStep : 68

You can then use it like :

if(event.Mode == 16)


// Check whatever you want


So, just in case, if you don't want which event is triggered, just add the
following line

in the onSave event of the form: