Azure emulator wont start as CacheInstaller has stopped working

Several times, I am getting CacheInstaller error as shown below during the starting up of Azure emulator from Visual Studio. Most of the cases I can just ‘Close the program’ and the emulator will continue to start.
cacheInstaller
But there was one occasion that the CacheInstaller error dialog kept coming up each time I closed the dialog; and since then the emulator won’t start. So I clicked the ‘Debug the program’ to attach the CacheInstaller to Visual Studio. And copy the error message in the CacheInstallationException dialog (shown below) to notepad.
CacheInstallationException
And below is the message I got from the exception:

An unhandled exception of type 'Microsoft.ApplicationServer.Caching.AzureServerCommon.CacheInstallationException' occurred in CacheInstaller.exe
Additional information: Install Manifests : Script completed with error: ExitCode: 2
ErrorStream: Configuration error.
Configuration error.

ERROR: wevtutil.exe im Microsoft.ApplicationServer.EventDefinitions.man failed with error 15010
OutputStream: F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\unlodctr.exe /m:Microsoft.ApplicationServer.Caching.PerformanceCounter.man

Info: Successfully uninstalled the performance counters from the counter definition XML file Microsoft.ApplicationServer.Caching.PerformanceCounter.man.
F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\wevtutil.exe um Microsoft.WindowsFabric.EventDefinitions.man

Provider Microsoft-Windows-Fabric{{751c9dc0-4f51-44f6-920a-a620c7c2d13e}} is missing channels under the channelreferances registry key.
F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\wevtutil.exe um Microsoft.ApplicationServer.Caching.EventDefinitions.man
F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\wevtutil.exe um Microsoft.ApplicationServer.Caching.TracingEventDefinitions.man
F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\wevtutil.exe um Microsoft.ApplicationServer.EventDefinitions.man
F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\lodctr.exe /m:Microsoft.ApplicationServer.Caching.PerformanceCounter.man
Info: Successfully installed performance counters in F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching\Microsoft.ApplicationServer.Caching.PerformanceCounter.man

F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>if 0 NEQ 0 (
echo.
 echo ERROR: lodctr.exe failed with error 0  1>&2
 exit /b 2
)

F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>C:\Windows\system32\wevtutil.exe in Microsoft.ApplicationServer.EventDefinitions.man
<b>Provider Microsoft-Windows-Fabric{{751c9dc0-4f51-44f6-920a-a620c7c2d13e}} is missing channels under the channelreferances registry key.</b>
F:\Projects\My Cloud Project\My Cloud Project\csx\Debug\roles\MyCloudWorkerRole\plugins\Caching>if 15010 NEQ 0 (
echo.
 echo ERROR: wevtutil.exe im Microsoft.ApplicationServer.EventDefinitions.man failed with error 15010  1>&2
 exit /b 2
)

From the highlighted message above, it is obvious that the wevtutil command is returning error (15010), instead of the expected value:0. And the error is something to do with some missing registry. Hmm, it looks like registry corruption and unfortunately I didn’t have restore point of my VM so that I could restore to the last working state. So I did more research on the wevtutil command, as for developer I am not really familiar with it. To cut the story short, the wevtutil command is provisioning/registering the custom event log defined in the EventDefinition.man file to the Event Viewer and it depends on the registry values in this locations: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Publisher]. Then I searched for registry key {751c9dc0-4f51-44f6-920a-a620c7c2d13e} under the Publisher node and find this node key: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Publishers\{751c9dc0-4f51-44f6-920a-a620c7c2d13e}] which is the event source for Azure Caching.

In the error message above it complains about missing channels. Under this registry node in my development VM, I only saw 2 channels (channel 1 and channel 2). So I did remote desktop to one of the worker roles in our UAT cloud services and check for this registry setting, and there were 3 channels (0,1, and 2). I added the channel 0 and their associated keys following the one in UAT and restart my visual studio. And finally I can debug my cloud project again.

Below is the registry settings that missing from my development VM:

CacheEventRegistry

Call Sharepoint Online CSOM from an external application

There might be time when an external application want to talk to SharePoint Online (Office 365) without user interaction. Below are several scenarios that we might want to use SharePoint 2013 resources from external applications such as:

  • A console/windows application/service to perform administration to Skydrive Pro or SharePoint Online
  • Use SharePoint Online resources from Azure worker role i.e. uploading documents to a document library or adding items in a list or interact with the workflow,etc

These are steps to allow an external application to use site collection resources:

Firstly, we need to register a new SharePoint app. If the external application needs to access a site collection in SharePoint Online for example https://mytenant.sharepoint.com/sites/dev, we need to register an app by going to an application page called appregnew.aspx. For site collection above, it will be https://mytenant.sharepoint.com/sites/dev/_layouts/15/appregnew.aspx.

appregnew.aspx

  • Generate Client Id – and copy it to notepad
  • Generate Client Secret – and copy it to notepad
  • Title is your app title
  • App domain, the domain of your app, or anything such as guid. I normally put a URI that identifies the external app
  • Redirect URI, can be blank or put the current site collection url where this app registered.

Then click create button, it will register an Azure AD’s Service Principal with Id equals to the Client Id. This Service Principal will allow the OAuth process between the external application and SharePoint Online. (You can run this command from Office 365 Powershell console  to get more information about the service principal: Get-MsolServicePrincipal -AppPrincipalId <Client Id>) This msdn article provides some guideline about registering SharePoint app.

Next step, we need to set the permission for the app by going to /_layouts/15/appinv.aspx. The permission will authorize the external application to access SharePoint resources.
appinv

  • App Id: copy the Client Id we created at the first step and click Lookup. it will populate the other information except the Permission Request XML.
  • In the Permission Request XML put the below xml. The AllowAppOnlyPolicy flags that the registered app can be access by external application regardless the user.
  • The scope represents the permission right that the app can have. I noticed that with Write permission I am still getting access denied for uploading documents or adding items in a list. So I need to have FullControl permission.
<AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
</AppPermissionRequests>

Off course you need to be a site collection admin to be able to set permission as above, then click Create and click Trust It on the next screen. If you want to call SharePoint CSOM against any personal sites in SkyDrive Pro you need to register the app to have full control with tenant scope http://sharepoint/content/tenant. But only tenant admininstrator can register an app with this scope. This article contains all possible scopes that you can use in app permission.

TenantIDBefore we jump to the code we need to get the Realm (in the case of SharePoint Online, it is the Tenant Id). Go to /_layouts/15/appprincipals.aspx and copy the GUID after the ampersand to notepad. Click the image for more detail

Now we’re ready to write code, in your external application project add the TokenHelper.cs, you can get the file from any SharePoint App project then put the appsettings in the project’s app.config or web.config that will be used by the Token Helper as below

<appSettings>
    <add key="ClientId" value="the-client-id"/>
    <add key="ClientSecret" value="the-client-secret"/>
    <add key="Realm" value="the-tenant-id"/>
  </appSettings>

These setting will be used by the Token Helper to perform the OAuth process. Below is the code to get the SharePoint Client Context that can be used to access the site collection in SPO using CSOM.

 public static ClientContext GetClientContextForApp(Uri siteUrl)
 {
    var SharePointPrincipalId = "00000003-0000-0ff1-ce00-000000000000";
    var token = TokenHelper.GetAppOnlyAccessToken(SharePointPrincipalId, siteUrl.Authority, null).AccessToken;
    return TokenHelper.GetClientContextWithAccessToken(siteUrl.ToString(), token);
 }

The GetAppOnlyAccessToken’s 3rd parameter is targetrealm, it sets to null as it uses the one set in the appsettings. If you want to retrieve the realm dynamically you can call TokenHelper.GetRealmFromTargetUrl method, but this will make another https roundtrip to Azure AD.

With this approach we can use SharePoint Online resources from any external applications such as Azure Worker can upload files to a document library or insert items to a List or kick of a workflow in SharePoint.