The CRM Grid – A Microsoft CRM Blog

Greg Owens’ rose-tinted MS-CRM mumblings

Debugging plug-ins in v4.0 (Updated)

(Updated 9th June 2009)

As you will know, the extensibility model for Microsoft CRM has changed in v4.0 and we now have a concept of plug-ins (instead of the callouts that were used in v3.0).

I’m not a particularly seasoned C# developer but having got a comfortable grasp of the language, I was struggling when it came to debugging my plug-in. I knew the general principles of debugging and thanks to the plug-in registration tool, could get my code to fire, but I couldn’t get it to debug. I can now and here’s what I did (note – no revelations here, I’m simply writing this for the benefit of other n00bs).

Please note, I still use Visual Studio 2005. I haven’t done this in any other version so there’s no point in me trying to write about it – please comment if you have and whether these steps differ.

  • So you’ve finished coding and are ready to deploy your assembly. Step one is to build your project via the Build… menu in VS.
  • Next you need to deploy your assembly to the development server. You’ll need to use the Plugin Registration Tool to do this. I usually opt to deploy to the database as this avoids me having to deal with “file in use” errors (see below).
  • In addition to deploying your assembly you must also place the debug symbols (.pdb file)  in  …\Program Files\Microsoft CRM\Server\bin\assembly. Once you’ve built your solution in Visual Studio, ensure that the latest copy of the .pdb file (look in your solution’s build directory) is copied to the aforementioned directory.  Every time you (re)build your  assembly you must copy the revised pdb file across.
  • After copying the pdb file, you’ll need to restart IIS using the iisreset command from the command prompt.  This is required so that the symbols can be read in (this step is also necessary sometimes in order to avoid “file in use” errors if you choose to deploy your assembly dll to disk) .  I usually add an iisreset command into my Post-Build script in Visual Studio, along with an xcopy command, to move the pdb file to the correct location after each build.
  • After running iisreset, you need to effectively “kick start” the CRM thread  by simply opening or refreshing any CRM page. This ensures that the w3wp process is available for the debugger to attach to.
  • The next step is to load your solution file up on the server. This of course requires Visual Studio to be installed on the development server. There may be alternatives to this approach (perhaps remote debugging or a test harness – see below) but I haven’t tried them.
  • With your solution open on the server, select Debug > Attach to Process and then select the w3wp.exe process from the the list. You may need to place a check in the “Show Processes from all users” and “Show processes in all sessions” in order to see w3wp.exe.
  • If you haven’t already done so, add some breakpoints to your code in VS by moving the cursor to the code you wish to break on and pressing [F9]. A red dot should appear in the margin.
  • Finally, go to CRM and do whatever is required (as per your plug-in registration) to fire your plug-in (i.e. create/delete/update an appropriate record)
  • The code should fire and reach your breakpoint in Visual Studio. You can step through the code a line at a time by press [F11] to advance to the next statement.

You might also be interested to hear that Akezyt Janedittakarn wrote on the MSCRM Team Blog about steps to aid the debug process using a test harness 

I’ve just found this article at sadev.co.za on how to debug CRM plug-ins remotely.

Microsoft CRM Development Environment (Part 2)

Part 2 of more than one post on the CRM Development environment.

I hope this post will prompt you to share your experiences of these tools and hopefully suggest others that may assist me and other readers with the CRM developments…


Useful Utilities

  • What is it?
    Joris Kalz’s Microsoft CRM Caching Tool
    What does it do?
    This simple utility runs as a Windows service on your (development) CRM server. Periodically it will ping a whole list of MS CRM URLs on your server and consequently keeps the web services “warm”. This is especially useful when the server has been rebooted and you’re accessing CRM for the first time.
    Where do I get it?
    Microsoft CRM Caching Tool (Joris’ blog)
  • What is it?
    Internet Explorer Developer Toolbar
    What does it do?
    This invaluable utility is simply a must-have if you are doing any clientside scripting for CRM. It’s a plug-in for Internet Explorer that provides a new toolbar that allows you to easily explore the DOM of any page you are looking at. After installing this utility, you can click on any object on the screen and see full details of its properties and CSS attributes. Furthermore you can even change some of these properties and see instant feedback on your screen.
    Where can I get it?
    The Internet Explorer Developer Toolbar (Microsoft Download Center)
  • What is it?
    Microsoft Script Debugger
    What does it do?
    It helps… debug scripts. Ok so that’s pretty self-evident. The point here is that IE does not come out of the box with a debugger for when clientside script. Although rudimentary, MSD gets the job done and is a lot more useful than deciphering a vague “Object Expected” error message!
    Where can I get it?
    The Microsoft Script Debugger (Microsoft Download Center)
    Further Reading
    Jonathan Boutelle has an excellent post on using the Script Debugger which is worth a quick read if you’ve not used it before.
  • What is it called?
    CrmDiagToolTurbo
    What does it do?
    This is a tremendously helpful tool that comes into its own when you encounter those infuriating “Contact your System Administrator” error messages. This tool turns all manner of logging and tracing on for your CRM Server and outputs reams of useful, readable plain text. All of the logs it creates can, I believe, be forced into being by changing the registry and a few other places, but this is all neatly handled in a simple winforms application. Perhaps the most useful element (in my experience) has been the ability to get full SOAP tracing from the MSCRM Services since you are then able to view the raw error message that lies behind bland end-user error messages (key violations for example).
    Where can I get it?
    CrmDiagToolTurbo and CrmDiagToolTurbo4 (Benjamin’s blog)
  • What is it called?
    JSLint
    What does it do?
    As far as I’m concerned, despite the fact that it is an insufferable pedant for syntax (probably a good thing, considering its purpose in life!), JSLint helps me to spot those simple but frustratingly impossible to spot syntax errors in your JavaScript code (missing or extra brackets are good examples!). Officially, it’s “a JavaScript program that looks for problems in JavaScript problems”. And it’s free (and nothing like as I,Robot as it may sound!)
    Where can I get it?
    You can’t “get” it, but can use it from Douglas Crockford’s site
  • What is it called?
    SQLInform
    What does it do?
    Hot on the heels of JSLint, how about something similar for your SQL code? It’s not quite a syntax checker, rather it “beautifies” your SQL code by applying regular formatting. I find this particularly useful when working with Reporting Services reports, where the IDE has a charming habit of reformatting all of your nicely structured SQL code into a contiguous ugly blob of words. Fine if you’re a computer but hard as heck to read and amend…SQLInform is Java based and can run in your web browser or there’s also a standalone version for while you’re on the train ;)
    Where can I get it?
    See Guido Thelen’s site for the hosted and downloadable versions
  • What is it called?
    TextPad
    What does it do?
    It is a plain old text editor. We all have our favourites and Textpad is mine. Some of the things I really like about it:

    • Regular expression based searches, within files and across directory trees
    • Macro support
    • Downloadable/customisable syntax files
    • Option of Microsoft-a-like shortcut keys

    Where can I get it?
    It’s not free, but it’s not pricey either (£16.50). See www.textpad.com

  • What is it called?
    HTML Match
    What does it do?
    It’s a visual differencing tool, designed for web pages but perfect for comparing all sorts of other (non-binary) files. I’ve found this useful when comparing lengthy program output during testing, muddled file versions when developing Javascripts and even for troubleshooting unexpected problems in Exported Customisation XML files.
    Where can I get it?
    Another really cheap tool at US$ 27.50. See http://www.htmlmatch.com/
  • What is it called?
    The Microsoft CRM forums
    What does it do?
    Often, all the things you can’t do yourself! There are three busy forums full of knowledgeable professionals and just as importantly, others with less knowledge but asking the questions you want the answers to! The forums are a trove of information and a brief search across the topics will often find an answer to the majority of CRM questions that occur.
    Where can I get it?
    Links to all three forums are available here

I’m sure there will be other things that occur to me for this list, but please comment to add your own to this discussion :)

Microsoft CRM Development Environment (Part 1)

Microsoft CRM development seems simple enough, but I thought I’d post on what my own development environment typically looks like and provoke a little feedback. Maybe there are some tips and tricks out there that we’re not sharing because we assume that everyone’s doing things the same way! And yes – I know some of this is probably REALLY basic stuff that everyone knows – but assumptions are bad (well, they can be) ;-)

This is part 1 of…. more than 1.

Virtual PC Images

MS VPC is an obvious choice since it is free and more importantly it’s portable but there are of course alternatives (I’ve not heard a bad word about VMWare yet). You can’t really try the VPC route with any old piece of kit though. I run my dev environment on a 2GB dual-core 2Ghz HP laptop. It’s not the quickest, but is perfectly comfortable for most things I throw at it.

A Microsoft CRM environment needs Active Directory, Windows Server 2003, IIS, SQL Server, Exchange, Outlook client, Microsoft Office… According to Simon Hutson at Microsoft this is at least 3 VPCs’ worth of applications.

There are blog postings (see further reading, below) which explain how to condense all this into one tidy little image which is great. On my first deployment however, I opted to avoid all the awkward registry hacks and first try running two VPCs – Active Directory and Exchange 2003 on one image and CRM/SQL/client on the other.

I have to say I haven’t been disappointed. Since Exchange and AD often don’t need to do much, I knocked the RAM down to 256MB for that image and give about 1.5 GB to the CRM/SQL machine. I also have the luxury of this laptop being a dedicated test environment that I use alongside my desktop PC.

I do occasionally have a few frustrations with the speed of web-services warming up, but even this has been alleviated to some extent by using the CRM Caching tool…

Further reading:

Bulk removal of “Primary Contact” field – not as easy as you’d think!

The concept of “Primary Contact” does not fit well with our business model. As a result, the “type” of contact that was being populated in that field varied widely – anything from MD to chief bottlewasher had been placed in there.

Suffice to say, it was agreed with the business that the solution to this was to rename the field to “Customer Service Contact” and flush the old data in that field. No problem – a two-minute job. Or so I thought.

My intended approach was to conduct an Advanced Find, then use Bulk Edit to remove the value from the lookup. No such luck – the net effect was that the CRM Application concluded I had made no change, looked at me quizzically and sniggered when I clicked on save.

The second approach is one I’ve used before: combine an Advanced Find with a temporary Manual Workflow rule to update a number of records at once. Curiously, “Primary Contact” is NOT a field that is available for the Update Entity action in CRMv3. How frustrating – I didn’t much fancy spending extended “quality time” with my CRM system, then going through all those records and manually deleting them. And frankly the idea of donning my surgical gloves slicing into the MSCRM database wasn’t too appealing either.

The successful solution? I created a temporary Contact “I-Am-Not-A-Real-Person-Prentend-Im-Not-Here”. I then used Bulk Edit to assign the Primary Contact field to use this new Contact. Finally, I expunged my Contact record, leaving the Primary Contact field fresh, clean and ready start its new life as a “Customer Services Contact” field.

One thing can be said for v3 – it often forces you to think more innovatively!

The underlying connection was closed: unable to connect to the remote server

Our MS-CRM deployment has a fairly simple, custom integration with our mainframe system. Nothing fancy, effectively just shunting XML files around to perform overnight and the occasional ad hoc data sync.

We farmed the coding out to a well-known implementation partner and received code which had been tested in their development environment. A little reconfiguration and we were good to go. The first few test files worked just great, so I started throwing some bigger files at it. Suddenly we were getting problems…

“The underlying connection was closed: unable to connect to the remote server.”

Strange – this hadn’t been seen in the development environment. The connection details were clearly correct too since half of the batch had been processed ok. There was little else to go on. Now we all know, usually Google Is Your Friend, but on this occasion all we could find were details of generic ASP.Net web service development issues almost exclusively caused by firewall and proxy issues – again, this couldn’t be the case since the batch was partway complete.

The developer was at a loss – he had done nothing out of the ordinary. We noted that the service would fail at roughly (though not exactly) the same point each time, so his only suggestion was to introduce forced delay between each call to the CRM WebServices. This was far from satisfactory, but fundamentally it worked (and we’d already exceeded allocated time on this simple service) so that was that.

Unfortunately I’m a persistent little bugger, so I couldn’t rest knowing there was an issue out there that we hadn’t identified! What seemed apparent was that this network issue was not at the transport layer or lower. I’m not a hardcore developer, but I remember that network ports can be opened/allocated on a dynamic basis. Don’t berate me but I think this is what is meant by “ephemeral ports”. Suffice to say, this seemed to fit the scenario – the server was running out of dynamic ports (or connections) to allocate to our batch service.

Anyway – I guess that that’s mostly just hot air: if you’re reading this post, there’s a good chance you’re having the same issue. The cause? It is acknowledged in Microsoft’s KB article: KB913515, but unfortunately you’ll need access to PartnerSource or CustomerSource to view.

The fix is made with a couple of changes to the registry to amend the machine’s TCP/IP configuration. If you can’t access the KB article above, I reckon I can probably point you to one of Microsoft’s publicly available pages which explains “WinTCP TIME-WAIT Delay“  (Win2k version here) and why you might need to amend the TcpTimedWaitDelay and MaxUserPort keys in the registry.

Please comment and let everyone know if this helped :)

Crikey… 2 months gone already?

Well, there was a deadline at work, then Christmas came and went, then there was new year and finally there’s been all sorts of fun and games the last couple of weeks (which I hope to post some exciting news about in the next few days) – but I hadn’t realised it had been so long since I last posted!

It seems there’s not a lot of new v3.0 postings being made now that v4.0 has emerged screaming; all pink and wrinkly. I have a few more things I want to share before v3.0 becomes old news ;)

A (slightly) different approach to dynamic picklists

The MS CRM client-side SDK has an example for filtering dynamic picklist values – an example in widespread use (Ronald has a post on this too). I found this example wasn’t flexible enough for handling situations where the list of picklist options might grow in the future, since it relies on “related” options being consecutive in the list. It also meant that an option can only apply to one “group”

This query has also just been raised by Naaz in the Microsoft Forums.

Here is the solution I used. I find it much more flexible than the SDK example, it just required a bit more coding! Read the rest of this entry »

Set users’ default Start Page

The Announcements module in MSCRM is potentially very useful to your deployment, especially during the early days of implementation (in my opinion). By directing all users via the Announcements page, it is possible to make sure they all see pertinent news or articles. The problem is that by default, a user’s Start Page is the Activities screen and unless you have particularly motivated and/or habitual users it will be difficult to get them to check Announcements on a regular basis.

The solution? Force their default Start Page to be “Announcements” – but how? There is no out-of-the-box solution available to the administrator. In fact the only supported method is to request each user to change the value themselves. Far from ideal, right?

Dejan Dular encountered the same problem so he did something about it. The users’ Start Pane and Start Tab are of course held in the database. Dejan found the appropriate fields in the _MSCRM database and updated them. Simple!

The basic code is copied below, but please be sure to thank Dejan via his blog if you found this to be useful.


UPDATE [UserSettingsBase] SET [HomepageSubarea] = 'nav_news', [HomepageArea] = 'Home'

As with all good things, this change is unsupported by Microsoft so the usual caveats apply!

Incidentally, we will be using the Announcements section to post links to self-help articles or reference documents to assist our users during early days of the deployment and to announce the inevitable post-implementation bugfixes.

More thoughts on managing your JavaScript code

Peter Maude made an interesting post, quite some time ago now, considering how one might manage the reams of JavaScript code that could potentially accompany a highly customised MS-CRM deployment.

I’ve pondered over this recently as I move from development to a live deployment and I migrate my custom JavaScripts from standalone .js files into the entity forms themselves. Presently I have some standard wannabe-global code for generic functions (such as show/hide elements of the UI), lots of entity-specific code in the onLoad event and often up to a dozen smaller script files which handle onChange events in various form controls.

Keen to make the effort to at least try and be in a supported environment, it strikes me that the simplest method is to put all of my code in the onLoad event handler and use the “attachEvent()” method to allocate functions to the appropriate form controls (thinking about it, this probably isn’t supported either…!). For example the code I currently use for each onChange event has its own .js file. I can simply copy this code, wrap it in an arbitrary function wrapper in the onLoad event handler and then attach that function as the onchange event for the field I want:

var fieldA_function = function exampleOnChangeFunction()
{
// function to be executed onChange of myfield A
alert('Field value is: ' + crmForm.all.new_myfielda.DataValue);
}
crmForm.all.new_myfielda.attachEvent("onchange", fieldA_function);

I haven’t tested this, but right now it feels logical enough. At the very least you will never have more script sources to manage as you have entities. I’d be interested to know your thoughts or ideas.

I’ve been wondering whether it might be possible to store code in a custom entity, e.g. called JavaScript and calling the code direct from the database… More on that when I’ve proven whether it’s possible or not!

Prevent caching of Javascript include files during development

Recommended JavaScript Book!

I'd also like to highly recommend this JavaScript book by Douglas Crockford - it will definitely improve the quality of your JavaScript development experience!

Surely everyone that does their own clientside Javascripting of the MS-CRM interface is already using the technique described by the almighty Ronald Lemmen to link to .js files to speed up the development process, since it removes the need to republish your entity forms over and over after each scripting change. Although unsuited for use in a production environment (for various reasons), this method has undoubtedly saved me hours in development time.

What I couldn’t understand though was why my updates often didn’t take effect, despite updating and saving my script files and even closing my browser. I even looked around for some evidence that I wasn’t the only one on the planet with this problem. Google suggested I was, so I had to find my own solution.

The problem appeared to be that the .js file was being helpfully cached in IE. By clearing my cache and fully reloading the page, I could solve the problem. Still, it was annoying. My preferred solution is a bit ugly but works a treat – when calling the JavaScript file, ensure that the script source is located at a unique URL each time the page loads. I use the getTime() method of the Date object to give a totally unique URL for that moment in time. The harness to load all my JavaScript files now looks like this:

var dt = new Date();
rndURL = "<script src='full_path_to_source_file.js?random='" + dt.getTime() + "' language='JavaScript'>";
st = document.createElement(rndURL);
h = document.getElementsByTagName('head');
h[0].insertAdjacentElement('beforeEnd',st);

Obviously this script is entirely unsupported by Microsoft, but if you happen to become the second person on the planet to experience the same caching issue I did, this just might save you some time.

Don’t forget that the first time you paste this code into your form onLoad event, you’ll need to republish your form, flush the browser cache, restart IIS, turn around three times then hit F5 in IE before the randomising magic works for you.

« Newer entries · Older entries »