Tuesday, 28 October 2014

Limit Regarding Lookup in MS Dynamics CRM 2013

So Today we had an interesting requirement: We had a custom entity, called Paper, for which we wanted to limit the entities that could be selected for the regarding lookup.

I can't come up with a supported way of doing this so this is the unsupported way:

In essence, this will limit the Regarding to new_keyissue and new_goal.

You'll need to fire it on the onChange event like this, NEW.Paper.limitRegardingLookup.

if (typeof (NEW) == "undefined")
{ NEW = {}; }
NEW.Paper = {
    limitRegardingLookup: function () {
        
        var KeyIssueOTC = GetEntityTypeCode("new_keyissue");
        var goalOTC = GetEntityTypeCode("new_goal");
  
        var ObjectTypeCodeList = KeyIssueOTC + ", " + goalOTC;
        var LookupTypeNames = "new_keyissue:"+ KeyIssueOTC + ":Key Issues,new_goal:" + goalOTC + ":Goal";
        
 Xrm.Page.getControl("regardingobjectid").setFocus(true);
  
        document.getElementById("regardingobjectid_i").setAttribute("lookuptypes", ObjectTypeCodeList);
        document.getElementById("regardingobjectid_i").setAttribute("lookuptypenames", LookupTypeNames);
        document.getElementById("regardingobjectid_i").setAttribute("defaulttype", KeyIssueOTC);

    }
};

function GetEntityTypeCode(entityName) {
    try {
        var lookupService = new RemoteCommand("LookupService", "RetrieveTypeCode");
        lookupService.SetParameter("entityName", entityName);
        var result = lookupService.Execute();
        if (result.Success && typeof result.ReturnValue == "number") {
            return result.ReturnValue;
        }
        else {
            return null;
        }
    }
    catch (ex) {
        throw ex;
    }
}

Sunday, 26 October 2014

Enable .NET Framework 3.5 in Windows 2012 Azure Virtual Machine (VM) - Error Code 0x800F0906

Yesterday I tried to install Ms SQL Server in a Azure VM that was running Windows 2012 R2, but it would complain about not being able to enable it.

So I tried from Server Manager and I got the following error:


Since this is a Azure VM, I don't think I should be downloading the Windows ISO, so ... well, it turns out that this is a known issue for which there is a fix, so all you need to do is apply the latest Windows updates and then it will install fine.

Control Panel -> Windows Updates


11 updates, WTF MS?


The one we care about.

The question I have is why in the name of all that is holy, isn't the fix already applied when the VM is provisioned? I get that MS can't just release a new image for every fix but preventing the install of SQL Server seems to be a big enough issue to warrant a new image, even if there are SQL Server VMs, but they are more expensive and .... at any rate, hope it saves people time.

I guess it's a matter of time, hopefully.

Monday, 20 October 2014

Validating SharePoint file names in JavaScript

SharePoint limits the valid characters of file names, which can be a problem, so to prevent this issue, we use this function to validated filenames in our Web App that integrates with SharePoint.

var validateFileName = function (value){

var specialCharacters = new RegExp("[\\\\\/:*?\"<>|#{}%~&]");

if (specialCharacters.test(value)) {      
 return true;
}
else{
 return false;
}

}
Only thing to note is that \\\\ is needed to represent \ in the regular expression, see this for more details

Tuesday, 30 September 2014

TIL - Format Guids to string in C#

Too long to explain, oh yes, it was SharePoint related, but I learnt today about various options for formatting Guids available in the framework:

Shameless copy and paste from this page.

Specifier
Format of return value
N
32 digits:
00000000000000000000000000000000
D
32 digits separated by hyphens:
00000000-0000-0000-0000-000000000000
B
32 digits separated by hyphens, enclosed in braces:
{00000000-0000-0000-0000-000000000000}
P
32 digits separated by hyphens, enclosed in parentheses:
(00000000-0000-0000-0000-000000000000)
X
Four hexadecimal values enclosed in braces, where the fourth value is a subset of eight hexadecimal values that is also enclosed in braces:
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}

So crmRecord.Id.ToString("N").ToUpperInvariant() results in : "7AD6FAB54528E411940D005056BC69C8"

Friday, 26 September 2014

TIL - Set EventId when Logging to the Event Log with Log4net

I used to be a fan of the Enterprise Library, but lately I've found myself using Log4net instead, which is not bad.

We wanted to log fatal errors to the event log, which can be easily done by configuring a trace listener, however we also wanted control over the event id displayed in the event log to allow meaningful monitoring

Turns out it's pretty simple:
log4net.ThreadContext.Properties["EventID"] = 1337;log.ErrorFormat("Elite Exception: {0}.",  ex); 


Tuesday, 23 September 2014

TIL - Create Scheduled Tasks with parameters using schtasks

Today I had to create a couple of schedule task to run this application I wrote, the problem was that when I did this:
schtasks /create /sc daily /tn "Application" /TR "'c:\Program Files (x86)\Application\Application.exe -t'" /ST 00:30:00 /RU user /RP password 
It created a task but then when it started, it would not actually run nor stop, so after a bit of googling and a few tries i came up with this
schtasks /create /sc daily /tn "Application" /TR "'c:\Program Files (x86)\Application\Application.exe' -t" /ST 00:30:00 /RU user /RP password 
Note how the command, in bold, is surrounded by single quotes and the whole, i.e. command and parameters is surrounded by double quotes, so this will run Application.exe with parameter -t @ 00:30 everyday
Hope it helps.

Monday, 22 September 2014

Remove Users from group in SharePoint 2013 from Client Object model.

This is the method that we use to remove users from groups in Sharepoint 2013

It's a bit more convoluted than it needs to be as for some reason Sharepoint 2013 appends the claim provider to the username, which means that rather than having:
 dev\duser1  
we have something like:
i:0#.w|dev\duser1  
so in order to ensure that the it will always find the relevant user, we do the extra call to ResolvePrincipal.

using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Utilities;

     public bool RemoveUser(string url, string groupName, string userName)  
     {  
       using (ClientContext context = new ClientContext(url))  
       {  
         var principal = Utility.ResolvePrincipal(context, context.Web, userName, PrincipalType.User,  
           PrincipalSource.All, context.Web.SiteUsers, false);  
         context.ExecuteQuery();  
         if (principal.Value != null)  
         {  
           string login = principal.Value.LoginName;  
           GroupCollection siteGroups = context.Web.SiteGroups;  
           Group group = siteGroups.GetByName(groupName);  
           var query = context.LoadQuery(group.Users.Where(usr => usr.LoginName == login).Include(u => u.LoginName));  
           context.ExecuteQuery();  
           User user = query.SingleOrDefault();  
           if (user != null)  
           {  
             group.Users.RemoveByLoginName(user.LoginName);  
             context.ExecuteQuery();  
           }
           return true;               
         }  
       }  
       return false;  
     }  

Monday, 1 September 2014

Product Versions in MSI installers created with WIX - part 2

In a previous post I described how to change the version of MSI installers created with WiX.

This post discusses a way of linking the version number of an assembly (library, dll, executable) to the product version.

This is more suited to a library/framework, where you want to ensure that the product version is the same as the library/framework.
  1. On the library project, edit the AssemblyInfo.cs file:

  2. Remove these two lines:
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]
  3. Create a new File called VersionInfo.cs on the Properties folder.

  4. Contents of file should be:
    [assembly: System.Reflection.AssemblyVersion("0.0.0.*")]
  5. Edit the project file (you'll need to unload the project if you want to do it from Visual Studio) and at the end, you'll find a commented out section. Get rid of it (everything between <!-- -->) and add the following:
  6. <Target Name="BeforeBuild"> < <WriteLinesToFile Condition=" '$(Version)' != '' " File="Properties\VersionInfo.cs" Overwrite="True" Lines="[assembly: System.Reflection.AssemblyVersion(&quot;$(Version)&quot;)] // Auto-generated by build process" /> </ </Target>
  7. On the product.wxs file on your WiX project, just add the following:
  8. <Product Id="12c0deff-c0de-c0de-c0de-123f422c0dea" Name="Name" Language="1033" Version ="!(bind.FileVersion.filAB3D3C60ED5901936249D5C56B6C90A6)" Manufacturer="ManyRootsofallevil" UpgradeCode="fafffaff-c0de-c0de-c0de-123f422c0dea">
    Where filAB3D3C60ED5901936249D5C56B6C90A6 is the id of your library file
  9. Finally, add the following to the wix project. Make sure this is on the initial PropertyGroup Element:
  10. <Version Condition=" '$(Version)' == ''">0.0.0.1</Version>
You can now build this using:

msbuild solution.sln /p:Version=1.3.3.7

Friday, 29 August 2014

TIL - Copy References in GAC to output folder

A while back I had this problem, looks like there is a simple solution:

<Reference Include="DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
 <SpecificVersion>False</SpecificVersion>
 <Private>True</Private> <HintPath>..\..\..\OpenXml SDK 2.5\DocumentFormat.OpenXml.dll</HintPath>
</Reference>
Setting <Private>True</Private> ensures that the reference is copied to the output folder, looks like setting it to Copy Local, just doesn't do the trick

Thursday, 21 August 2014

TIL - DeploymentItem files not copied in MSTest

I have a set of unit tests that need an xml file to work  and I despite me using the DeploymentItem attribute the test was not working.

Turns out that DeploymentItem will only copy from the build directory, so I set the Copy to Output Directory property of the file to Copy always: