August 10, 2012

Mapping SkyDrive, DropBox etc. folder to drive

This post is not related to MS CRM in any way, but it might come handy so I thought it’s worth sharing.

When installing cloud based storage like SkyDrive or DropBox you get a nice link in the Favorites section of Windows Explorer. Something like this:
image

This works very nice until the application shows you the “modern” save or open file dialog.

But what happens if an application is “legacy” or for some different reasons (I’m guessing Java) is using the older versions of the dialogs. You get something like this (example is from Adobe Reader X):
image

Navigating to your cloud based storage gets a little annoying. You have to click [Computer], [C],  [Users], [USER_NAME], [SkyDrive]. That’s 5 clicks just to get to the stupid folder. Someone could say that you only need to type in "%UserProfile%\SkyDrive, but lets be honest – that’s not something most of us think of in such situations (also moving the hand away from the mouse in order to type is quite annoying Smile ).

Wouldn’t it be nice to be able to map such folders to a drive letter? That way it’s only 2 clicks away.

The solution is quite easy – a windows command called subst. The syntax is as follows:
C:\Users\kowgli>subst /?
Associates a path with a drive letter.

SUBST [drive1: [drive2:]path]
SUBST drive1: /D

  drive1:        Specifies a virtual drive to which you want to assign a path.
  [drive2:]path  Specifies a physical drive and path you want to assign to
                 a virtual drive.
  /D             Deletes a substituted (virtual) drive.

Type SUBST with no parameters to display a list of current virtual drives.

So in my case just typing in subst Z: C:\Users\kowgli\SkyDrive almost solves the problem. The problem is this is not persistent across system reboots. In order to overcome this one of the simple solutions is to ensure the command gets executed each time the system start – read HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

image

Adding the command to that registry area solves the problem. And now our folder is permanently mapped to a drive, which saves us 3 clicks a couple of times per day Open-mouthed smile

I know for some people this problem is trivial, but still … I thought it would be nice to share.

Cheers

August 9, 2012

CRM 2011 plugin registration error “Inheritance security rules violated by type”.

When trying to register a plugin using an external dll ILMerged into it I came across the following error:

Unhandled Exception: System.TypeLoadException: Inheritance security rules violated by type: 'XXX.YYY.ZZZ.Plugins.ABC'. Derived types must either match the security accessibility of the base type or be less accessible.
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()

I remembered I had this issue before. The reason is that some legacy external libraries don’t follow .NET 4.0 security rules. The solution it actually quite simple – revert back to .NET 2.0 security. Simply add the following attribute anywhere inside you’re code (after the using statements):

[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]

July 31, 2012

CrmSvcUtil error - Exiting program with exception: The parameter is incorrect.

When trying to run the proxy generation tool after getting back from vacation I got the following error:
Exiting program with exception: The parameter is incorrect.

image

Simple solution – delete LiveDevice.xml file from %UserProfile%\LiveDeviceID

June 18, 2012

SSRS Division Helper App. Avoid errors in division result. (SQL Server Reporting Services)

A quite common issue in SSRS is getting properly displayed values when dividing 2 numbers. When the denominator is equal to 0 or NULL you get an ugly looking error or “Infinity” in the field. Not really what the customer would like to see.
A well known solution is when dividing A / B to do something like this:
= IIF(  IsNothing( B )
        OR B = 0,
        0,
        A
        /
        IIF( IsNothing( B )
            OR B = 0,
            1,
            B
        )
)

Writing this each and every time gets a little annoying. With the not so good code editor in BIDS when we have complex expressions instead of “A” and “B” it can actually be very frustrating and unnecessarily time consuming.
Having to do this over and over again I made a small and very simple tool I would like to share.
image
All you need to do is put the required values in the top and bottom. Click [Generate] and copy the result.
It saves some time and I hope someone finds it useful.
Download from here.
Source (VS 2010)

June 1, 2012

CRM Online Reports – visible previously internal parameters not showing up

Simple use case – I wanted to update a existing report setting a couple of report parameters to visible, which were previously set to internal. It showed up nicely in Visual Studio but although I updated the report a couple of times in CRM Online the report parameters were still not visible. I made sure the report itself was actually updated by adding some dummy text to it, but the parameters stayed hidden. It looked like the report parameter settings in SSRS weren’t really refreshing during the update.
The solution I found was actually quite simple. I deleted the report and uploaded it once again. Then the report parameters showed up nicely. It’s not rocked science but might come in handy for someone.

October 17, 2011

Strange behavior of LINQ XRM data context – Ghosts

Recently I experienced a lot of problems when creating a complex plugin which played around with thousands of records.

When using good, old T-SQL you would experience the following behavior:

Id Name
1 AAA
2 BBB
3 CCC

SELECT Name FROM Table WHERE Id = 2
Result: AAA

UPDATE Table SET Name = ‘ZZZ’ WHERE Id = 2

SELECT Id FROM Table WHERE Name = ‘ZZZ’
Result: 2

Being naïve and lazy I expected the same behavior from the LINQ 2 CRM data provider – wrong! Remember about caching. This doesn’t happen every time, but from time to time, especially when doing operations one after another querying for a value you just set a moment before, will simply return NULL. This off course caused a lot of strange and hard to find errors.

In CRM it sometimes works like this:
SELECT Name FROM Table WHERE Id = 2
Result: AAA

UPDATE Table SET Name = ‘ZZZ’ WHERE Id = 2

SELECT Id FROM Table WHERE Name = ‘ZZZ’
Result: NULL

Off course when doing a standard FetchXML or QueryExpression everything is OK.

The solution – recreate the Data Context before each query – dataContext = new DataContext(), or as minimum before each query to an entity you used before. This will of course lower the performance a little, but let’s be honest 99,99% of the time is spend inside the query.

To be completely fair I have experienced similar issues with the “Portal Extensions” from CRM 4 but didn’t think Microsoft made CRM 2011 backward compatible in this matter Uśmiech

The SDK makes the impression that the LINQ queries are simply translated into QueryExpressions, apparently they are not.

Differentiating between NULL and NO CHANGE in CRM 2011 plugins

Unfortunately a NULL value of a field in the plugin target can have 2 meanings:

  1. Value has been changed to NULL (new value equals NULL)
  2. Value has not changed (new value equals old/current value)

I’m referring to values of properties when using the strongly typed approach like:

Microsoft.Xrm.Sdk.Entity target = ExecutionContext.InputParameters["Target"] as Entity;
Account account = target.ToEntity<Account>();
string name = account.name;

Thus it could be illustrated something like this:

Plugin target “New” value
NULL ???
VALUE VALUE

Where the plugin target is the value of the attribute taken from the target entity in the plugin and the "new" value is the value that will be saved to the DB.

Shortly speaking we don’t know the “new” value in 50% of cases.

Adding a pre entity image will lower this to 75%.

Pre Entity Image Plugin target “New” value
NULL NULL NULL
NULL VALUE VALUE
VALUE NULL ???
VALUE_1 VALUE_2 VALUE_2

So if the plugin target has any value then that is off course the “new” value.If it’s NULL and the pre image value is also NULL we are sure that the new value is NULL.

The only way to get to 100% I could think of is to get back to the not type safe, property bag approach, because if we just use:
entity.Attributes[“name”]
instead of
account.name
we actually get the information because the value is either NULL if it was set to NULL or it’s not there at all (throwing a value not found exception).

This gives:

Pre Entity Image Plugin target Property bag “New” value
NULL NULL Doesn’t matter NULL
NULL VALUE Doesn’t matter VALUE
VALUE NULL Has attribute NULL
VALUE NULL Doesn’t have attr. VALUE
VALUE_1 VALUE_2 Doesn’t matter VALUE 2

I summed this up in this little piece of code:

private object TrueValue(object preValue, object targetValue, Entity target, string attributeName)
{
    if (preValue == null || targetValue != null)
    {
        return targetValue;
    }
    else
    {              
        if(target.Attributes.ContainsKey(attributeName.ToLower()))
        {
            return null;
        }
        else
        {
            return preValue;
        }               
    }
}

Which could be used like this:

Account preImage = this.ExecutionContext.PreEntityImages["PreImage"].ToEntity<Account>();
string newName = (string) TrueValue(preImage.name, account.name, target, “name”);

It could be simplified so that it doesn’t use the typed account property at all (it’s basically the same as the property bag).

The scenario can get even more complicated when using field level security. In those cases a NULL value can have 3 meaning:

  1. Value has been changed to NULL
  2. Value has not change
  3. User (in whose context the plugin is executed) has no READ privilege to the field

The simplest solution seems to run plugins, which touch secured field, in the context of an administrative user (impersonate).