Geeks With Blogs
Inside Microsoft Dynamics CRM 3.0 Arne Janning

So... I didn't post for a long time, I have been on holidays since new year, didn't have an internet connection for a long time - I actually write this from an internet cafe.

In my last post I promised to show how to get inside CRM and do customizations that go far beyond of what is supported. I also already mentioned the main entry point of the whole CRM-web-application, which is the Microsoft.Crm.MainApplication.Application_OnStart()-method in Microsoft.Crm.Application.Pages.dll. Microsoft.Crm.MainApplication is referenced in the global.asax-file in the CRM-webroot:

<%@ Application language="c#" Inherits="Microsoft.Crm.MainApplication" CodeBehind="Microsoft.Crm.Application.Pages.dll"%>

<%@ Application language="c#" Inherits="Microsoft.Crm.MainApplication" CodeBehind="Microsoft.Crm.Application.Pages.dll"%>

<%@ Application language="c#" Inherits="Microsoft.Crm.MainApplication" CodeBehind="Microsoft.Crm.Application.Pages.dll"%>

<%@ Application language="c#" Inherits="Microsoft.Crm.MainApplication.Application" CodeBehind="Microsoft.Crm.Application.Pages.dll"%>

We will write our own CRM-host to get inside CRM and get access to the internal CRM-object model at runtime. This is fairly easy.

First of all, create class library project in Visual Studio .NET 2003 - it must be .NET 1.1. In my example the project has the name "Janning.Crm.Host".

Then make sure you have added the following references:

  • System.dll
  • System.Data.dll
  • System.XML.dll
  • System.Drawing.dll
  • System.Web.dll
  • Microsoft.Crm.dll (from the GAC)
  • Microsoft.Crm.Application.Components.Application.dll (from \bin)
  • Microsoft.Crm.Application.Components.Core.dll (from \bin)
  • Microsoft.Crm.Application.Components.Platform.dll (from \bin)
  • Microsoft.Crm.Platform.Sdk.dll (from the GAC)

There is a small trick to copy assemblies from the GAC : Press Start --> Run and then enter C:\Windows\assembly\gac. The shell extension which is normally running on the assembly-folder won't show up then and you can easily copy and paste the CRM-assemblies and reference them from VS.NET.

Then you have to add the following code into a codefile:

using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Security.Principal;
using System.Web;
using System.Web.SessionState;
using System.Xml;

using Microsoft.Crm;
using Microsoft.Crm.Application.Platform;
using Microsoft.Crm.Errors;
using Microsoft.Crm.Metadata;
using Microsoft.Crm.Security;
using Microsoft.Crm.Utility;

namespace Janning.Crm.Host
{
 public class CustomCrmApplicationHost : HttpApplication
 {
  protected void Application_Start(Object sender, EventArgs e)
  {
   RegControl.LoadLibraries();
   NotificationManager.ExtraParameter = HttpContext.Current;
   MetadataCacheConfig.LoadMethod = LoadMethod.Database;
   NotificationManager.StartNotificationsThread(new Notification());
  }

  protected void Application_AuthenticateRequest(Object sender, EventArgs e)
  {
   try
   {    
    UserCache.GetCurrentUser();
   }
   catch (Exception ex)
   {
    COMException comex = ex as COMException;
    string errorCode = "0xffffffff";
    if (comex != null)
    {
     errorCode = comex.ErrorCode.ToString("x", CultureInfo.InvariantCulture);
    }
    string redirectPath = string.Format(
     CultureInfo.InvariantCulture,
     "/_common/error/authenticationError.htm?0x{0}&{1}",
     errorCode,
     base.Request.Url.AbsoluteUri);
    base.Response.Redirect(redirectPath);
    base.Response.End();
    CrmTrace.TraceFormat(
     TraceCategory.Application,
     TraceLevel.Error,
     "An error occurred during the Application_OnAuthenticateRequest : \nError: {0} \nStack Trace:{1}",
     ex.Message,
     ex.StackTrace);
   }
  }

  protected void Application_Error(Object sender, EventArgs e)
  {
   base.Response.Clear();
   Exception ex = base.Server.GetLastError();
   ErrorInformation info = new ErrorInformation(ex, base.Request.Url);
   if (ConfigurationSettings.AppSettings["DevErrors"] != "On")
   {
    info.StackTrace = string.Empty;
   }
   if (info.Source == "XML")
   {
    base.Response.ContentType = "text/xml";
    ErrorInformation.XmlSerializer.Serialize(base.Response.OutputStream, info);
    base.Response.End();
   }
   else if (info.Source == "SOAP")
   {
    base.Response.Clear();
    base.Response.ContentType = "text/xml";
    base.Response.StatusCode = 500;
    XmlTextWriter writer = new XmlTextWriter(base.Response.Output);
    writer.WriteStartDocument();
    writer.WriteStartElement("soap", "Envelope", "
http://schemas.xmlsoap.org/soap/envelope/");
    writer.WriteStartElement("Body", "
http://schemas.xmlsoap.org/soap/envelope/");
    writer.WriteStartElement("Fault", "
http://schemas.xmlsoap.org/soap/envelope/");
    writer.WriteElementString("faultcode", "Server");
    writer.WriteElementString("faultstring", info.Description);
    writer.WriteStartElement("detail");
    ErrorInformation.XmlSerializer.Serialize(writer, info);
    writer.WriteEndDocument();
    base.Response.End();
   }
   else
   {
    HttpException httpEx = ex as HttpException;
    string maxRequestLenghText = "Maximum request length exceeded.";
    string pathFileName = Path.GetFileName(base.Request.Path);
    if ((pathFileName == "print_data.aspx") || (base.Request.Path == "/crmreports/download.aspx"))
    {
     base.Response.ClearHeaders();
    }
    if ((pathFileName == "importFieldMap.aspx") && (httpEx.ErrorCode == -2147467259) && ((ex.InnerException != null) ? (maxRequestLenghText == ex.InnerException.Message) : true))
    {
     base.Server.ClearError();
     base.Response.Redirect("/Tools/BulkImport/importFileChoose.aspx?errorMessage=BulkImport_Error_Exceed_MaxFileSize");
     base.Response.End();
    }
    else if ((pathFileName == "upload.aspx") && (httpEx.ErrorCode == -2147467259))
    {
     base.Server.ClearError();
     base.Response.Redirect("/_common/error/uploadFailure.aspx?hr=0x80043e08");
     base.Response.End();
    }
    else if (pathFileName == "print_data.aspx")
    {
     base.Server.ClearError();
     base.Response.Redirect("/_common/error/popuperror.aspx?hr=" +
      httpEx.ErrorCode.ToString());
     base.Response.End();
    }
    else if (ConfigurationSettings.AppSettings["DevErrors"] == "On")
    {
     //left this out for the moment
    }
    else
    {
     base.Response.Redirect(
      "/_common/error/errorhandler.aspx?errNum=" +
      HttpUtility.UrlEncode(info.Code) +
      "&errMessage=" +
      HttpUtility.UrlEncode(info.Description));
     base.Response.End();
    }
   }
  }
 }
}

Compile the code into an assembly, copy the assembly into the \bin-folder, make a backup of the global.asax-file and change the global.asax-file to this:

<%@ Application language="c#" Inherits="Janning.Crm.Host.CustomCrmApplicationHost" CodeBehind="Janning.Crm.Host.dll"%>

<%@ Application language="c#" Inherits="Janning.Crm.Host.CustomCrmApplicationHost" CodeBehind="Janning.Crm.Host.dll"%>

<%@ Application language="c#" Inherits="Janning.Crm.Host.CustomCrmApplicationHost" CodeBehind="Janning.Crm.Host.dll"%>

<%@ Application language="c#" Inherits="Janning.Crm.Host.CustomCrmApplicationHost" CodeBehind="Janning.Crm.Host.dll"%>

(If your assembly-name or namespace is different you have to change this of course)

Make an iisreset (Start --> Run --> iisreset) and open CRM again: http://yourCrmServerOrIP

Everything just works exactly like it did before, there is only one difference: if you use a tool like Process Explorer and look which dlls are loaded into the w3wp.exe-process you'll see that the Janning.Crm.Host.dll is actually running in the process. As the code in this assembly which is running in the most central part of CRM is now completely under your control you can do pretty much anything - if you know the internal object model. I'll write about this soon in detail and give you a couple of examples.

I should mention again that all this is of course completely unsupported by Microsoft, me or my future employer.

If someone wants to have the complete VS.NET-solution-files then just leave a comment here and I'll send it via email. I have no access to an FTP-server at the moment so I can't offer a download - perhaps someone has some empty space for me? :-)

(And please, could somebody explain me how to use the font sizes in .Text-Admin - I simply don't get it)

Posted on Saturday, January 28, 2006 3:35 PM | Back to top


Comments on this post: Getting inside Microsoft CRM - Part I

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files .
TIA
Shai
Left by Shai on Jan 28, 2006 9:04 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Have you tryied this for the cassiniclient? There is not support for offline CRUD thru sdk objects.
JDE
Left by Offline mode? on Jan 30, 2006 6:33 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
For the Outlook client you cn use the metadataservice for access of the metabase, but the CrmService won't work. For that you need to use direct data access into the MSDE database...
Left by LIZ on Feb 02, 2006 10:54 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
I need it.thx.
Left by Meteor on Feb 06, 2006 4:58 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files .

alperc@datasistem.com.tr
Left by Alper Can on Feb 07, 2006 7:23 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
I'm very interested in your code files.
my email: maeseleg at delaware.be
Left by Geert on Feb 14, 2006 3:22 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files . That is very useful for me
my mail id.. jebin_blessed@yahoo.com
Left by Jebin on Feb 15, 2006 5:06 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files
My ID: piyushjazz_2002@rediffmail.com

Regards,
Piyush
Left by Piyush on Mar 08, 2006 8:44 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
I would like your VS.NET-solution-files. My email is vastalderaan@yahoo.com.

Thanks,

Wil
Left by Wil on Mar 09, 2006 9:54 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files
My ID:venkata@punditsguild.com
Left by VenkataRaviKumar on Mar 13, 2006 8:44 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files
My ID: venkata@punditsguild.com
Thanks
venkataravikumar
Left by VenkataRaviKumar on Mar 13, 2006 8:47 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files .
Thanks,
schinkel_erik@hotmail.com
Left by Erik on Mar 20, 2006 9:46 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET-solution-files .
Thanks,

Frank
fvharen@senet.nl
Left by fvharen on Mar 21, 2006 11:46 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
I followed the procedure but I can't see where the Janning.Crm.Host.dll in the w3wp.exe proces is. I opened CRM, which works just fine.
Left by fvharen on Mar 22, 2006 6:52 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi Arne,

This is a very nice way of getting access to the CRM host.

Could you send me the VS.Net files ?

Thanks in advance.
Stephane@dorrekens.com
Left by Stéphane on Mar 22, 2006 11:13 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,

Very good job!
Could you send me the VS.Net files ?


xwagner@gmail.com
Left by wagner on May 03, 2006 2:06 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Could you send me the VS.Net files ?
undead@iafrica.com

when is Part 2 coming
Left by Robert on May 26, 2006 9:23 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi
Please provide the complete VS.NET-solution-files .

my email id is : vrp822001@gmail.com
Left by Patel Vipul on Jun 16, 2006 5:48 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,

Very good job!
Could you send me the VS.Net files ?
Left by Oguz on Jul 28, 2006 12:54 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Very impressive, this will alow me to experiment to my hearts content, please send the VS.Net files.
shainefisher@hotmail.com
Left by Shaine Fisher on Aug 31, 2006 8:01 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,
could you send me the VS.Net files ?
Left by Manish Dixit on Sep 13, 2006 4:39 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
I'd really appreciate if you could send me the VS.Net solution

Thanks!
Left by P on Sep 14, 2006 5:12 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,
Can you please send me the VS.Net solution at purvichheda@gmail.com

Thanks!
Left by PC on Sep 14, 2006 5:13 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hello-

Could you please send me the VS.NET files?
gk@lexitroninc.com
Left by GK on Sep 21, 2006 8:16 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
hello

please can you send me the VS.Net solution at belk.mans@gmail.com

Thank you

Left by belkacem on Jan 09, 2007 1:37 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
I would love the source code.
Please send it to sbishop AT statera.com.
Left by Chane on Jan 17, 2007 10:09 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
hope i could get a copy of your code.
richardlaunio@yahoo.com.ph
Left by ledrahc on Feb 28, 2007 9:45 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please send me one copy as well. Thanks very muchl

alvinsue at hotmail dot com
Left by alvin on Mar 05, 2007 11:22 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,
I like the way you get into the MS CRM. Great Job.

Do mail me the VS Solution file. murali.tk@gmail.com.
Left by Murali on Mar 21, 2007 10:28 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Can you please send me VS.net the code and/or sample code, Also I can help you with your need for web space.

Great job!
Thanks in advance
Abe Saldana.
Left by Abraham Saldana on Apr 18, 2007 3:40 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi
Please provide the complete VS.NET-solution-files .

my email id is : anshul2005@gmail.com
Left by Anshul on Aug 29, 2007 2:49 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,

please provide the complete VS.NET solution files.
My eMail is:
christian.havel@c4b.de
Thanks
Christian
Left by Christian Havel on Oct 10, 2007 6:47 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Hi,

Please provide the complete VS.NET solution files.
My Email is:
milkywayz@hotmail.com
Left by Geraldine on Nov 20, 2007 9:15 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Can you please send me the source code at the following mail id Kibs75@yahoo.com
Left by Kirubakar on Feb 21, 2008 6:27 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET solution files.
My Email is:
dydesai@gmail.com
Left by Dhaval Desai on May 27, 2008 1:35 AM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please upload the code files, that shall be really helpful. thanks.
Left by CRM Developer on Jun 05, 2008 11:38 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Please provide the complete VS.NET solution files.
My Email is:
gprofet@zonnet.com
Left by Geron on Jul 02, 2008 2:39 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Sorry, little typo on my previous post.
Email should be: gprofet@zonnet.nl
Left by Geron on Jul 02, 2008 2:40 PM

# re: Getting inside Microsoft CRM - Part I
Requesting Gravatar...
Great job!!!!

Can you send me the source at johnny3627@gmail.com
Left by johnny on Feb 18, 2009 4:33 PM

Your comment:
 (will show your gravatar)


Copyright © Arne Janning | Powered by: GeeksWithBlogs.net