Unable to initialize the native configuration support external to the web worker process

This error came up using XrmToolBox and Visual Studio tools I wrote, which worked perfectly before.
Before what?
Before the update to Windows 10 build 1903.

Error
Unable to initialize the native configuration support external to the web worker process (HRESULT=0x80040154). nativerd.dll must be in %windir%\system32\inetsrv.

Fix

Hope it helps!

Power on…

Query all CRM databases for empty Transaction Currency fields

 

Sometimes it’s really handy to loop all CRM DBs in search of the value of some field for all organizations. This query results in all DBs + Tables + Columns + Number of empty Transaction Currency Ids

Use this at will for any analysis.

 

SET NOCOUNT ON
GO
use master
GO

DECLARE
@dbsql nvarchar(max),
@dbname nvarchar(500),
@dbid uniqueidentifier,
@variable2 int,
@variable3 int,
@totaldb int = 0,
@totaldbonserver int = 0,
@totaldbwithmatches int = 0

-- Get CRM databases
DECLARE DBCursor CURSOR for SELECT DatabaseName, Id FROM MSCRM_CONFIG.dbo.Organization

OPEN DBCursor
fetch next from DBCursor into @dbname, @dbid

while (@@FETCH_STATUS <> -1)
    BEGIN       
        DECLARE @ParmDefinition NVARCHAR(500)
        DECLARE @columncountquery nvarchar(500) = 'select @variable2OUT = count(*) from dorcastest_mscrm.INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME = ''TransactionCurrencyId'''

        SET @ParmDefinition = N'@variable2OUT int OUTPUT'
        set @totaldbonserver = @totaldbonserver + 1

        EXEC sp_executesql @columncountquery, @ParmDefinition, @variable2 OUTPUT
            print 'Number of TransactionCurrencyId-columns in ' + @dbname + ': ' + CONVERT(varchar, @variable2)

       if @variable2 > 0
        BEGIN
        declare
                  @columncursor     as cursor,
                  @columnsql        as nvarchar(max),
                  @columnquery      as nvarchar(max),
                  @table_catalog    as nvarchar(255),
                  @table_schema     as nvarchar(255),
                  @table_name       as nvarchar(255),
                  @column_name      as nvarchar(255),
                  @columncount      as int = 0

                  set @columnquery = 'select ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.TABLE_CATALOG,
                  ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.TABLE_SCHEMA,
                  ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.TABLE_NAME,
                  ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME
                  from ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS, ' + @dbname +  '.INFORMATION_SCHEMA.TABLES
                  where ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.table_catalog = ' + @dbname +  '.INFORMATION_SCHEMA.TABLES.table_catalog
                  and ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.table_schema= ' + @dbname +  '.INFORMATION_SCHEMA.TABLES.table_schema
                  and ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.table_name = ' + @dbname +  '.INFORMATION_SCHEMA.TABLES.table_name
                  and ' + @dbname +  '.INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME = ''TransactionCurrencyId''
                  and ' + @dbname +  '.INFORMATION_SCHEMA.TABLES.TABLE_TYPE = ''BASE TABLE'''

                  set @columnsql = 'set @cursor = cursor forward_only static for ' + @columnquery + ' open @cursor;'

                  exec sys.sp_executesql
                        @columnsql
                        ,N'@cursor cursor output'
                        ,@columncursor output

                  fetch next from @columncursor into @table_catalog, @table_schema, @table_name, @column_name
                  while (@@fetch_status = 0)
                  begin
                      declare @currencyidsql nvarchar(max) = 'select @variable3OUT = count(*) from '+ @table_catalog + '.' + @table_schema + '.' + @table_name + ' where transactioncurrencyid is null'
                      declare @Parm3Definition NVARCHAR(500) = N'@variable3OUT int OUTPUT'

                    EXEC sp_executesql @currencyidsql, @Parm3Definition, @variable3 OUTPUT
                    if @variable3 > 0
                              begin      
                                   print  @table_catalog + '.' + @table_schema + '.' + @table_name + '.' + @column_name + ' : ' + CONVERT(varchar, @variable3)
                              end

                        fetch next from @columncursor into @table_catalog, @table_schema, @table_name, @column_name
                  end

                  close @columncursor
                  deallocate @columncursor
        END   

        fetch next from DBCursor into @dbname, @dbid

    END

    /*
    PRINT 'Total CRM databases on server: '
    PRINT @totaldbonserver
    PRINT 'Total CRM databases tested () : '
    Print @totaldb
    PRINT 'Total CRM databases with matches: '
    Print @totaldbwithmatches
    */

CLOSE DBCursor
DEALLOCATE DBCursor

 

Skip the annoying MS CRM 2013/2015 splash screen

Obviously solution this doesn’t apply to CRM Online.

1. Start Registry Editor.

2. Locate registry subkey: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM.

3. Right-click MSCRM, point to New, click DWORD (32-bit) Value, enter DisableNavTour, and then press ENTER.

4. Right-click DisableNavTour, click Modify.

5. In the Value data box, type 1, and then press ENTER.

6. Close the Registry Editor.

Tuning MS CRM 2011 Performance

 

Voor Performance verbeteringen op SQL heb ik de afgelopen dagen de volgende resources gebruikt

Voor onze klanten die SQL2012 draaien zijn de volgende Performance Dashboard Report een uitkomst.
Features zoals Missing Indexes zijn een uitkomst… hiervoor is dus geen SQL trace en SQL optimizer meer nodig… zo lijkt het.

Microsoft® SQL Server® 2012 Performance Dashboard Reports
http://www.microsoft.com/en-us/download/details.aspx?id=29063
http://www.mssqltips.com/sqlservertip/2670/install-sql-server-2012-performance-dashboard-reports/

Verder levert een overvollen AsyncOperationBase ook performance problemen, zie hiervoor het volgende artikel.
Performance is slow if the AsyncOperationBase table becomes too large in Microsoft Dynamics CRM
http://support.microsoft.com/kb/968520

 

Dan is er nog de kwestie van de PrincipalObjectAccess tabel, die ook kan groeien tot meer dan één miljoen.
Hiervoor is ook een MS supported oplossing beschikbaar.
How to control PrincipalObjectAccess table growth in Microsoft Dynamics CRM 2011
http://support.microsoft.com/kb/2664150

 

En… de http://CRMJOBEDITER.CODEPLEX.COM is onmisbaar voor het correct schedulen van de ReindexAll, Deletion Service etc..

Dus..!

MS CRM 2011 Outlook Client x64 on Windows8

With many thanks to Merlin Schwaiger – Senior CRM Consultant at PowerObjects for writing this post on how to support MS CRM 2011 Outlook Client on Windows and Outlook 2013.

http://crmwizard.blogspot.nl/2011_02_01_archive.html

Long story shortened:

  • The x64 installer for the CRM 2011 Outlook client does not include everything necessary for the client to work.
  • You must download the x64 installer for SQL Compact 3.5.
  • You must upgrade the x64 version of SQL Compact 3.5 to version 3.5.8082.0 with the hotfix.
  • At this point the Outlook client should be able to connect to your CRM 2011 organization.

Load JavaScript WebResource at runtime

Update... added Browser-agnosticity


function LoadWebResource(resource)
{
   var httpRequest = _createXMLHttpRequest();
   httpRequest.open("GET", Xrm.Page.context.getServerUrl() + "/webresources/" + resource, false);
   httpRequest.send(null);
   try {
      eval(httpRequest.responseText);
   }
   catch (e) {
      alert("Error loading " + resource + ":\n" + e.description);
   }
}

// Browser-agnostic factory function
function _createXMLHttpRequest()
{
   if (window.XMLHttpRequest) {
      return new XMLHttpRequest();
   } else if (window.ActiveXObject) {
      return new ActiveXObject('Microsoft.XMLHTTP')
   } else {
      _error("Could not create XMLHttpRequest on this browser");
      return null;
   }
} 


------



function LoadWebResource(resource) {    var orgName = Xrm.Page.context.getOrgUniqueName();    var httpRequest = new ActiveXObject("Msxml2.XMLHTTP");    httpRequest.open("GET", "/" + orgName + "/webresources/" + resource, false);    httpRequest.send(null); try {       eval(httpRequest.responseText); } catch (e) {       alert("Error loading " + resource + ":\n" + e.description);    } }

How to make MS CRM 2011 ADX Studio Customer Portal MultiLingual

I had some issues making the ADX Studio Customer Portal multilingual.
First I tried having a duplicate website with duplicatie site markers and all… this was way too much.

I solved it just a little easier… use as much translations from CRM as possible… since there are a whole load of translations available when you install a language pack.
In this article I use Dutch and English.

First let me show you the markup for a page with a grid view displaying CRM data.

asp:GridView
ID=”GridView1″ runat=”server” CssClass=”cases” AutoGenerateColumns=”False”
>


<Columns>

    <asp:TemplateField
HeaderText=”Study”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader1″ runat=”server” Text=’<%# GetHeaderText(“cbr_study”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

        <asp:HyperLink
ID=”hlUrl” runat=”server” NavigateUrl=’<%# EducationUrl( (Guid)Eval(“cbr_educationid”) ) %>

Text=’<%# Eval(“cbr_study”)%>
/>

        </ItemTemplate>

    </asp:TemplateField>

    <asp:TemplateField
HeaderText=”Institution”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader2″ runat=”server” Text=’<%# GetHeaderText(“cbr_institutionid”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

            <%#
ContentUtility.FormatCrmEntityReference(Eval(“cbr_institutionid”) as
CrmEntityReference) %>

            <%# Eval(“cbr_institute_not_listed”)%>

        </ItemTemplate>

    </asp:TemplateField>

    <asp:TemplateField
HeaderText=”Start Date”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader3″ runat=”server” Text=’<%# GetHeaderText(“cbr_startdate”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

            <%# GetLocalDate(Eval(“cbr_startdate”) as
DateTime?) %>

        </ItemTemplate>

    </asp:TemplateField>

    <asp:TemplateField
HeaderText=”End Date”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader4″ runat=”server” Text=’<%# GetHeaderText(“cbr_graduationdate”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

            <%# GetLocalDate(Eval(“cbr_graduationdate”) as
DateTime?)%>

        </ItemTemplate>

    </asp:TemplateField>

    </Columns>

</asp:GridView>

 

In the code behind of this page, you´ll need the method GetHeaderText… taking the CRM field name as only argument..

In the Session-object I stored MyLanguageCode… holding the 1033 or 1043… whatever the user picked as display language.

 

protected
string GetHeaderText(string crmField)

{

return
ContentUtility.GetLocalizedLabel(XrmContext, crmField, “cbr_education”, (int)Session[“MyLanguageCode”]);

}

 

I add in the ContentUtility class a two methods … GetLocalizedLabel and GetLocalizedPickListValues

 

public
static
string GetLocalizedLabel(XrmServiceContext context, string crmField, string crmEntity, int LanguageCode)

{


RetrieveAttributeRequest CrmAttributeRequest = new
RetrieveAttributeRequest();

CrmAttributeRequest.EntityLogicalName = crmEntity;

CrmAttributeRequest.LogicalName = crmField;

 


RetrieveAttributeResponse response = (RetrieveAttributeResponse)context.Execute(CrmAttributeRequest);

 


if (response.AttributeMetadata.DisplayName.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).Any() == true)

{


return response.AttributeMetadata.DisplayName.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).SingleOrDefault().Label;

}

 


// Otherwise return the default label


return response.AttributeMetadata.DisplayName.LocalizedLabels.Single().Label;

}

 

public
static
ListItemCollection GetLocalizedPickListValue(XrmServiceContext context, string crmField, string crmEntity, int LanguageCode)

{


RetrieveAttributeRequest CrmAttributeRequest = new
RetrieveAttributeRequest();

CrmAttributeRequest.EntityLogicalName = crmEntity;

CrmAttributeRequest.LogicalName = crmField;

 


RetrieveAttributeResponse response = (RetrieveAttributeResponse)context.Execute(CrmAttributeRequest);


PicklistAttributeMetadata picklist = (PicklistAttributeMetadata)response.AttributeMetadata;

 


ListItemCollection ddItems = new
ListItemCollection();


string _localizedlabel = string.Empty;

 


foreach (OptionMetadata option in picklist.OptionSet.Options)

{


if (option.Label.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).Any() == true)

{

_localizedlabel = option.Label.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).SingleOrDefault().Label;

}


else

{

_localizedlabel = option.Label.LocalizedLabels.Single().Label;

}

 

ddItems.Add(new
ListItem(_localizedlabel, option.Value.ToString()));

}


return ddItems;

}


 

The length of the ‘filteringattributes’ attribute of the ‘sdkmessageprocessingstep’ entity exceeded the maximum allowed length of ‘100’

 

While developing a plug-in for CRM 4.0 triggers can be set when the plug-in can be set off using the Plugin Registration Tool.

When too many triggers are selected the following error will occur.

Unhandled Exception: System.Web.Services.Protocols.SoapException: Server was unable to process request.
Detail:

A validation error occurred. The length of the ‘filteringattributes’ attribute of the ‘sdkmessageprocessingstep’ entity exceeded the maximum allowed length of ‘100′.
Platform

at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at PluginRegistrationTool.CrmSdk.CrmService.Create(BusinessEntity entity)
at PluginRegistrationTool.RegistrationHelper.RegisterStep(CrmOrganization org, CrmPluginStep step)
at PluginRegistrationTool.StepRegistrationForm.btnRegister_Click(Object sender, EventArgs e)

 

What is de filteringattribute attribute?

While registering a plugin trigger in the CRM database the [<OrganizatioName>_MSCRM].[SdkMessageProcessingStepBase] table is updated.
For every plugin step a record is created in this table.
One of the attributes in this table is

[FilteringAttributes] [nvarchar](256)
NULL

During the registration of the plugin step the MetadataSchema is checked and validated a.o. the MaxLength of this attribute.

SELECT Maxlength
FROM [<OrganizationName>_MSCRM].[MetadataSchema.Attribute]
wHERE name =’filteringattributes’

By default the result of this query will be ‘100’. Strange of course since the database will allow to insert nvarchar strings up to 256 characters.

A solution could be

Update [<OrganizationName>_MSCRM].[MetadataSchema.Attribute
SET Maxlength = 256
where name =’filteringattributes’

If the MaxLength is set to more then 256 a SQL Error may occur since data will be truncated.

Note: After an update IISReset /noforce is required.

Note: Above customization is unsupported and you must take precautionary measure to make sure to avoid any problem with CRM system.

Multiple SSL secured site on IIS7

Let’s say that you have

  • an IIS7 webserver running
  • Microsoft Dynamics CRM is running on your webserver
  • And there’s another site running on the same webserver.
  • And both site are internet facing and need to be SSL secured

IIS Management Console doesn’t give you the possibility to do that.
You used to do this in IIS6 using adsutil.vbs

cscript.exe adsutil.vbs set /w3svc/<replace with your site id>/SecureBindings “:443:www.domain1.com”

IIS7 support is now delivering this option:

C:\Windows\System32\inetsrv>appcmd set site /site.name:”<Replace with your site name>” /+bindings.[protocol=’https’,bindingInformation=’*:443:<replace with your url>’]

Good configin’

Copying Dynamics CRM form values to the clipboard

For multiple records MS CRM options like mail merge and Excel exports are mighty handy.
For single record data export the Clipboard is more the way to go.

If you need the name and address of a certain account or contact … you want that to be directly available… in your CTRL-V.
If you want to print using a label printer… perhaps.
Exporting it to Excel or starting the Mail Merge may be a bit much to do… you for one record.

Start using this option… an ISV button “Copy name and address to clipboard” executing a JavaScript copying certain values to the clipboard.

OnLoad

CopyToClipboard =

    function () {

        // Construct the string you want on the clipboard.

        var sClipBoard = crmForm.all.firstname.DataValue + ” ” + crmForm.all.lastname.DataValue + “\n” +

                       crmForm.all.address1_line1.DataValue + “\n” +

                       crmForm.all.address1_city.DataValue + “, ” + crmForm.all.address1_stateorprovince.DataValue + ” ” + crmForm.all.address1_postalcode.DataValue;

        // Use/Create a input area

        var oClipBoard = document.getElementById(“ClipBoard”);

        if (oClipBoard == null) {

           oClipBoard = document.createElement(“input”);

           oClipBoard.setAttribute(“id”, “ClipBoard”);

           oClipBoard.setAttribute(“type”, “hidden”);

            document.getElementById(“crmForm”).appendChild(oClipBoard);

            }

        // Put in the clipboard string

        oCopyArea.innerText = sClipBoard;

        // Now copy to the string clipboard

        var oCopyText = oCopyArea.createTextRange();

        oCopyText.execCommand(“Copy”);

        };

 

Make the function available as an ISV button:

 
 

        <Entity name=”contact” >

          <ToolBar>

            <Button JavaScript=” CopyToClipboard ();” Icon=”/_imgs/ico_16_132.gif” ValidForCreate=”1″ ValidForUpdate=”1″ AvailableOffline=”true”>

              <Titles>

                <Title LCID=”1033″ Text=” Copy name and address to clipboard ” />

              </Titles>

              <ToolTips>

                <ToolTip LCID=”1033″ Text=” Copy name and address to clipboard ” />

              </ToolTips>

            </Button>

          </ToolBar>

        </Entity>