Request a topic or
contact an Arke consultant
404-812-3123
Arke Systems Blog | Useful technical and business information straight from Arke.

Arke Systems Blog

Useful technical and business information straight from Arke.

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Archive

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2014

Microsoft Dynamics CRM 4.0 Update Rollup 3 released

While at Convergence last week, Microsoft went ahead and released Update Rollup 3 for CRM 4.0.  You can get it here.

A few important notes:

  • Importing and exporting customizations is supported between servers with Update Rollup 2 and 3, but not supported between Release, Rollup 1 and Rollup 3. 
  • The CRM for Outlook Client has some memory usage issues resolved.
  • Performance issues with CRM related to the email router have been resolved.

Categories: CRM
Posted by Wayne Walton on Tuesday, March 17, 2009 10:26 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Truncate_Only no longer supported in SQL Server 2008

If you've ever used the Truncate_Only to shrink logs in SQL Server 2000/2005, it may come as a surprise to you that its use has been discontinued in SQL Server 2008.

Instead, you can use the following commands to get SQL Server to do essentially the same thing:

 
Alter Database %databasename% Set Recovery Simple

 And then

Alter Database %databasename% Set Recovery Full

You can then shrink the log file as normal.


Categories: SQL Server
Posted by Wayne Walton on Monday, March 16, 2009 3:04 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Unable to load client print control – SSRS and CRM

After some Googling, I came across this forum post: http://social.microsoft.com/Forums/en-US/crm/thread/b86740b6-6418-4e1c-9020-1d6c9c630b7b/

Basically a hotfix KB956391 broke the client control for SSRS.  We had already installed all the latest automatic updates on all the servers, but the following update isn’t presented with Windows Update.

http://www.microsoft.com/downloads/details.aspx?FamilyID=82833f27-081d-4b72-83ef-2836360a904d&DisplayLang=en

Installing this fix on ALL* related servers, then rebooting fixed the problem.  (*You can’t just install it on the SSRS machine, you need to install it on any server that allows a client to connect to reporting services.) 

Basically, this fix forces the browser to download the latest client viewer and install it.  I had found a number of other solutions that required a manual installation on the client’s computer, but this one works from the server side.


Categories: CRM | SQL Server | SSRS
Posted by Trenton Adams on Wednesday, March 11, 2009 5:53 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Importing related records in CRM from CSV

So it is a common issue that when new CRM clients (especially CRM Online clients) come online, they have data they need to import.  Well, not all of them have proper databases, or even really a budget to get a custom-developed import solution, or Scribe.  Well, we've put together a budget-oriented method that can help.

First off, the most common issue is that the client has their info in just one big Excel file.  Contacts, Company, Notes and maybe even Opportunities are all in one big flat file.  Well obviously that won't do for CRM.  However, if you just break them up into different files and upload, they aren't associated with one another.  Now if you only have a few dozen contacts and companies, it might be ok to go in after the fact and set them manually, but that's not going to be a viable solution for most.  So we need a way to associate all these different entities.

Fortunately, CRM makes a unique identifier for every record it creates (called a GUID), and we can use this record to tie record types together.  However, to do this, you're going to need a couple tools.

1. The Microsoft CRM Data Migration Manager.  This comes in both a local/hosted version and a CRM Online version. Don't get these confused, they are not compatible.  Also, I very strongly recommend setting up a virtual machine to install these on, it will save you a lot of heartache in the future, and you can avoid some "gotchas" about how the DMM works on a clean VM.

2. The CRM Bulk Data Export Tool.  This is Arke Systems' updated version of the Bulk Data Export Tool. The changes we made include being able to get GUIDs out of CRM, and not having to set a date limit for how much data you're getting out of CRM.  If you have any trouble with the app, please post the errors, and we can take a look. It's not technically a supported app by us or by MS, but I'll try to help.

So now that we have the tools we need, let's get down to brass tacks.  First things first, extract the information you need about the Account into its own CSV file.  At the minimum, you'll need a Company Name.  Once you have that file, go ahead and upload it to CRM via the Data Migration Manager.  Once that's done, open up the Bulk Data Export Tool. Authenticate to your CRM, and then export the Accounts back out.  Make sure to set in the dropdown that you want the IDs exported too.  That this does is give us the GUID of every Account you just uploaded to CRM.

Below: The Bulk Export Tool.  Important field highlighted in red.

Now that we have those GUIDS, we need to find a way to set those in your Contacts list (or whatever list you need to associate with those Accounts).  Sure, you could just copy and paste those GUIDs next to the appropriate contact, but that would take forever.  What we need is a little Excel magic.  First, you're going to need to understand how to use the OFFSET and MATCH functions in Excel. Say you have an Excel document with two sheets in it (this can also work across documents).  the first one has a list of all companies and the related GUIDs.  The second one has a list of contact names and the companies they are part of.  So on the Contacts sheet, you're going to add two more columns, Match and Account ID.  On the Match column, you're going to write something like this: =MATCH(A2,Sheet1!A:A,0).  What that tells me is that on Sheet1 (where the Company list resides), I want to find the relative position of the Company Name and report a row number back.  On the Account ID column, you'll put something that looks like this: =OFFSET(Sheet1!$B$2,Sheet2!B2-2,0). What that means is that you want Excel to go look on Sheet1 and grab the GUID relative to the Match number you've pulled to Sheet2 (the Contacts sheet).

Below: Sheet2 and Sheet1 examples

So now you should have a list of contacts that also has a list of GUIDs under the heading Account ID.  Save that file as a raw CSV, it's time to go back to the Data Migration Manager.  Start another migration with your contacts, and match up fields like normal until we get to the Account ID. For this one, we're going to do things a little different.  First, select the field in CRM called "Parent Customer".  When you do, it should take you to another page asking you to link up this field with one in Accounts.  That's good, we want that. So select the dropdown that says Account ID and continue on.

Assuming the rest of the migration goes smoothly, you should be able to go into a Contact and see that it has a Parent Customer all set. If you prefer to have the Primary Contact field in Accounts populated instead, just reverse the order of uploads.  Do Contacts first, and then upload Accounts with the Primary Contact ID instead. Speaking of which, that is a limitation of this method.  You will always have one standalone Entity at the beginning (normally Accounts or Contacts).  I have not found a good way around that, yet.

So I hope that helps all of you that have been struggling with a simple, yet reasonably effective way of importing data to CRM on a budget.  Please hit up the comments with suggestions on improving this, or any questions you have about the process!

Categories: CRM
Posted by Wayne Walton on Monday, March 02, 2009 12:09 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Deploying IIS dlls, part 2

Following up on my previous post about copying some CRM Plugin DLLs after a build ( http://arkesystems.com/blog/post/2009/02/Recycling-IIS-app-pools.aspx ):

It turns out that the error checking in post-build events isn't reliable (it only checks errorlevel at the end of the script), and apppools don't stop instantly even when told to stop instead of recycle. 

So if my xcopy encounters a "sharing violation" (errorlevel 4) then the post-build event isn't smart enough to notice by default.

Luckily, it's just a bat file, so we can add some checking ourselves.  This is getting more complicated than I would like, but at least I build reliably now.

"sleep" isn't necessary, but it's a useful command to have around.  It comes with Windows 2003 Server Resource Kit: http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&DisplayLang=en ; restart visual studio after installing the kit.

A note on checking return codes in batch files: Equality checks are actually 'greater than or equal', so you will see people checking if errorlevel eq 1 often.  However, this only catches >= 1 error levels, and the occassional program that returns negative error codes will slip past.  Accordingly, always check "neq 0" instead of "eq 1".  Also, using "SETLOCAL ENABLEDELAYEDEXPANSION" and !ERORRLEVEL! is not strictly necessary in this script, but it's good practice to just always use delayed expansion when checking return values in batch files so that you don't screw up one day when you write an error check inside a loop.

So, hopefully my final iteration of a post-build script that needs to update some IIS dlls:

SETLOCAL ENABLEDELAYEDEXPANSION 
net pause KeepAliveService 
cscript /nologo "$(ProjectDir)\iis_stop_app_pool.vbs" "CRMAppPool" 
if !ERRORLEVEL! NEQ 0 GOTO FAIL 
set CRMDIR=C:\Program Files\Microsoft Dynamics CRM 
set loop=0 
:TRYCOPY 
set /a loop=%loop%+1 
xcopy "$(TargetPath)" "%CRMDIR%\Server\bin\assembly" /i /d /y 
if !ERRORLEVEL! NEQ 0 GOTO COPYFAIL 
xcopy "$(TargetDir)$(TargetName).pdb" "%CRMDIR%\Server\bin\assembly" /i /d /y 
if !ERRORLEVEL! NEQ 0 GOTO COPYFAIL 
cscript /nologo "$(ProjectDir)\iis_start_app_pool.vbs" "CRMAppPool" 
if !ERRORLEVEL! NEQ 0 GOTO FAIL 
net continue KeepAliveService 
GOTO OK 
:COPYFAIL 
if %LOOP% LEQ 10 GOTO TRYCOPYSLEEP 
goto FAIL 
:TRYCOPYSLEEP 
sleep 1 
goto TRYCOPY 
:FAIL 
echo "Failed with errorlevel !ERRORLEVEL!" 
exit 1 
:OK 
echo "OK" 

Edit 3/30/2010: For a 64 bit system, you can get silently redirected to SysWOW64 when a 32 bit process is trying to run something in system32.This causes iisapp.vbs to fail when run as a post build event. In Visual Studio, it shows as an exited with code 1 error. If you manually go to the [windows]\SysWOW64 folder and run iisapp.vbs, you can get an error like:Could not create an instance of the CmdLib object.Please register the Microsoft.CmdLib component.

One solution is to copy the necessary files to the SysWOW64 folder and reregister the dlls:
cd c:\windows\SysWOW64
copy ..\system32\iisapp.vbs .
copy ..\system32\IIsScHlp.wsc .
copy ..\system32\cmdlib.wsc .
regsvr32 cmdlib.wsc
regsvr32 IIsScHlp.wsc

 

Posted by David Eison on Friday, February 27, 2009 5:23 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Recycling IIS app pools

When developing for Sharepoint or working on CRM DLLs, you need to recycle the IIS app pool a fair bit.

 

Maybe I’m late to the party and everyone already knows this, but just in case, this utility for resetting iis app pools rocks: http://www.harbar.net/articles/APM.aspx 

 

You can also recycle an app pool in a script with

cscript c:\windows\system32\iisapp.vbs /a "CRMAppPool" /r 

But, for my CRM DLL, I need a post-build event that stops the app pool before I copy a DLL.  I tried simply using iisapp.vbs to recycle, but this failed sometimes because the DLL can still be in use after the restart (I'm not sure if it restarts too fast, or if it due to overlapped recycling).

Based on posts from http://mscrm4ever.blogspot.com/2008/12/expediting-plug-in-development-using-vs.html and http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_21362452.html , I ended up with the below.

My post-build event:

cscript /nologo "$(ProjectDir)\iis_stop_app_pool.vbs" "CRMAppPool"
set CRMDIR=C:\Program Files\Microsoft Dynamics CRM
xcopy "$(TargetPath)" "%CRMDIR%\Server\bin\assembly" /i /d /y
xcopy "$(TargetDir)$(TargetName).pdb" "%CRMDIR%\Server\bin\assembly" /i /d /y
cscript /nologo "$(ProjectDir)\iis_start_app_pool.vbs" "CRMAppPool"

 

The stop and start scripts: 

iis_stop_app_pool.vbs:

Option Explicit
Dim apool, strComputer, objWMIService, colItems, objItem
apool = WScript.Arguments.Item(0)
strComputer = "."
Set objWMIService = GetObject _
    ("winmgmts:{authenticationLevel=pktPrivacy}\\" _
        & strComputer & "\root\microsoftiisv2") 
Set colItems = objWMIService.ExecQuery _
    ("Select * From IIsApplicationPool Where Name = " & _
        "'W3SVC/AppPools/" & apool & "'")
 
For Each objItem in colItems
  Wscript.Echo "Stopping " & objItem.Name    
  objItem.Stop
Next

iis_start_app_pool.vbs:

Option Explicit
Dim apool, strComputer, objWMIService, colItems, objItem
apool = WScript.Arguments.Item(0)
strComputer = "."
Set objWMIService = GetObject _
    ("winmgmts:{authenticationLevel=pktPrivacy}\\" _
        & strComputer & "\root\microsoftiisv2") 
Set colItems = objWMIService.ExecQuery _
    ("Select * From IIsApplicationPool Where Name = " & _
        "'W3SVC/AppPools/" & apool & "'")
 
For Each objItem in colItems
    Wscript.Echo "Starting " & objItem.Name
    objItem.Start
Next

Posted by David Eison on Friday, February 27, 2009 1:09 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Microsoft Dynamics CRM 4.0 rsLogonFailed

Problem:

Web service request SetParameters to Report Server /reportserver">http://<machinename>/reportserver failed with SoapException. Error: Logon failed. (rsLogonFailed)

image

 

Fix:  Turn off the Execution Account.  Yes that’s correct, having the Yellow Warning sign is the correct setting.

image


Posted by Trenton Adams on Tuesday, February 03, 2009 7:24 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Useful CRM links

For those of you who are looking for resources to help with CRM issues, or just to keep up on the news of CRM, I wanted to provide a few links.

So I hope that helps anyone looking for solutions and/or community for CRM.  If you are in LinkedIn, there are numerous CRM groups there as well.

Finally, Update Rollup 2 for CRM 4.0 has been released!  Get those patches up and running.


Categories: CRM
Posted by Wayne Walton on Thursday, January 22, 2009 11:30 AM
Permalink | Comments (0) | Post RSSRSS comment feed

IE, hover, and transparent PNGs

IE, particularly IE6, has a few quirks that anybody working on websites needs to know about.  Luckily there are workarounds, but unfortunately the workarounds for different problems don't always play nice with each other.

1) Transparent PNGs don't work right by default.  Inside an image tag, the alpha channel of a transparent png will be ignored in IE6, leading in my case to very ugly corners on a rounded window.  To fix this, you need to use CSS to specify a "filter" to have IE display the image with a different image display routine.  The easy approach is to run some javascript to go back and rewrite all your images if you're in IE6; scripts like SuperSleight or Unit PngFix will go through and dynamically change your page to use filters for PNGs.  Unfortunately, I've had bad luck combining these scripts with other fix scripts; on my latest project I ended up doing all of my PNGs with external style sheets, then including an IE6 specific style sheet using conditional comments, and manually setting the PNG filters in the style sheet.  If you're doing it manually, note that you may also run into IE z-index problems, in my case it was on some input boxes, that may be solvable by putting the problem elements inside a position:relative container and manually setting their z-index.  Yes, the position:relative shouldn't be necessary, it's just a bug workaround.

2) CSS "Hover" doesn't work right except for links in IE6.  Particularly, it doesn't work on images, so if your client wants an image to light up when the mouse is over it, you're going to have to deal with this.  Adding javascript "onmouseover" and "onmouseout" events can make hover work by dynamically swapping the CSS class when the mouse triggers the javascript.  The easiest way to do this is 'whatever:hover'; it's a .htc file that you add to the CSS for the body of your page via the IE-specific 'behavior' property, and it automatically tracks down your hover classes and adds the necessary Javascript to invoke them.  If doing it manually, what you want are onmouseover and onmouseout events that change the CSS class, coupled with CSS classes that specify the non-hover and hover behavior you want - but you only need this for IE6, so it's probably best not to do it manually because the conditional comments throughout your code will get ugly quick.

Unfortunately, whatever:hover and unitpngfix didn't play nice together for me.  Manually doing the PNG fix was an acceptable workaround, and had the added benefit of not waiting for the page to load before swapping the pngs.

3) CSS "Hover" doesn't work right except for links in IE7 unless you set a strict doctype.  So, your first step is to set a strict doctype for IE7 to work right.  The main thing to be aware of when setting a strict doctype is that browsers become less forgiving; in particular, in-line elements can not have a width and height specified, so your stylesheets will need to explicitly set "display:block" if you were forcing widths and heights on spans.  Also be aware that your box model will change, from the IE specific quirks model to the actual correct spec, but you were probably dealing with that already due to cross-browser compatability.

I'm sure there are more troubles you will run into, but these were the main ones that caused an IE6 headache on my latest project.  I've found plenty of info on getting PNG transparency to work, and plenty on getting hover to work, but nothing on both together.  It can be done, but the easy drop-in fixes might not be enough for you and it pays to understand what the root problem they are addressing is.


Posted by David Eison on Tuesday, December 16, 2008 3:52 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Hiding and Changing Left Navigation Items in CRM 4.0 Entity Screens

First off, I want to give a big thank you to Jeremy Winchell for writing up the post that got me started in the right direction for this solution.

For those of you that customize Microsoft Dynamics CRM 4.0, like I do, then likely one of the things you repeatedly run into is clients and users that need to have better names for their actions.  Changing these names on the main navigation page relatively simple, but what about on all the other pages, like Contacts, Accounts, etc.?  These, for whatever reason Microsoft had, aren't removable or changeable.  It's a really painful oversight to have to tell a client that even though you have renamed "Products" to "Hardware", they're going to have to remember that it's still going to be "Products" in a few places.  Hopefully the next version of CRM will have the capability to alter and remove these natively, but until then, we'll have to roll our own.

 Warning, the following actions are not supported or even documented by Microsoft.  Use at your own risk.

Now that the disclaimer is out of the way, let's take a look at the meat of the solution.  First, go to the customization area of the Entity you want to change, and open its form view.  In there, click Form Properties and enable JavaScript for the OnLoad action.  The link above has pictures if you're not sure how to get there.

Now you will need the JavaScript:
document.getElementById("%variableName%").style.display = "none"

So in this line, %variableName% is the variable related to the button on the left-hand nav.  “none” will hide this element entirely.  (Also, make sure if you copy and paste that you don’t end up with retarded Word-style quotes.  That happened to me and I spent 10 minutes trying to find a typo in my code)

If you want to change the display name of a button, then you have a bit more work to do.

Again, the JavaScript:
document.getElementById("%variableName%").innerHTML= "<img src=\"%imageLocation%\" /> %displayName%";

Here, you will see that we’re using innerHTML to actually change the content of that button.  Now you don’t have to have the image code in here, but if you leave it out, then your link won’t have an image anymore, and will just be text.  If you want to keep the image, the best thing I have found is to use the IE Dev Toolbar and then look at that button’s properties (to get the IE Dev toolbar on a popup screen, hit Ctrl+N).  You will see the link to the default image there.  This is going to be different for every CRM install, so I have not included it on the table below. Then just change the Display Name with whatever you want the button to actually say, and you’re set!  Note that the quotes around the image location have to be escaped.

Below is a list of the links, their variable names, and their default Title.  From there, making changes to the left nav of any entity in CRM should be simple.   You will see repeats of some.  The reason for that is because MS was not 100% internally consistent in its naming scheme.  For example, Cases is IDed by both navService and navCases, depending on where you are.  For those, I would either try both, or check on the screen itself.

Link

Link ID Name

Default Title

Activities

navActivities

View Activities

Campaign Activities

navCampaignActivities

View Campaign Activities

Campaign Responses

navCampaignResponses

View Campaign Responses

Campaigns

navCampaignsInSFA

View Campaigns

Campaigns

navCampaignsInList

View Campaigns

Cases

navService

View Cases

Cases

navCases

View Cases

Competitors

navComp

View Competitors

Competitors

navComps

View Competitors

Contacts

navContacts

View Contacts

Contacts Excluded

navBulkOperationFailures

View Contacts Excluded

Contacts Selected

navTargetedMembers

View Contacts Selected

Contract Lines

navContractLines

View Contract Lines

Contracts

navContracts

View Contracts

Documents

navDoc

View Documents

E-mail Messages Created

navBulkOperationSuccesses

View E-mail Messages Created

Existing Products

navExistingProducts

View Existing Products

History

navActivityHistory

View History

Information

navInfo

View general information about this record

Invoices

navInvoices

View Invoices

Marketing List Members

navListMember

View Marketing List Members

Marketing Lists

navListsInSFA

View Marketing Lists

More Addresses

navAddresses

More Addresses

Opportunities

navOpps

View Opportunities

Orders

navOrders

View Orders

Other Contacts

navContacts

View Other Contacts

Planning Tasks

navTasks

View Planning Tasks

Price List Items

navPrices

View Price List Items

Products

navProducts

View Products

Quick Campaigns

navMiniCampaignsForList

View QuickCampaigns

Quotes

navQuotes

View Quotes

Related Campaigns

navCampaigns

View Related Campaigns

Relationships

navRelationships

View Relationships

Sales Literature

navCollaterals

View Sales Literature

Sales Literature

navSalesLit

View Sales Literature

Sub-Accounts

navSubAct

View Sub-Accounts

Sub-Contacts

navSubContacts

View Sub-Contacts

Substitutes

navSubs

View Substitutes

Target Marketing Lists

navTargetLists

View Target Marketing Lists

Target Products

navTargetProducts

View Target Products

Workflows

navAsyncOperations

View Workflows

Write-In Products

navWriteInProducts

View Write-In Products

 

So now you should have all the tools you need to customize the Entity Screens into something useful for your clients and users.  And don't forget, if you break something, you can always just delete the JavaScript and start over.


Posted by Wayne Walton on Tuesday, October 14, 2008 2:30 PM
Permalink | Comments (0) | Post RSSRSS comment feed