Walkthrough : Debugging an Office Add-In Project


Recently, I have worked for a Word AddIn project, but I cannot debug or run it because the required version of Microsoft Office was not installed. Visual Studio show for me this error « you cannot debug or run this project because the required version of the microsoft office application is not installed »

To resolve this issue, you should do these actions :

1.       Go to the project properties in Visual Studio

2.       Go to the 'Debug' tab

3.       Click the 'Start external program' radio button

4.       Enter the path to the Office Application e.g. « C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE »

5.       Run the project.

Install an assembly into the Global Assembly Cache without gacutil

When we need to register an assembly in the GAC, generally we use the Global Assembly Cache tool (Gacutil.exe) with this command gacutil -i <assembly name>

But Gacutil.exe is only for development purposes and should not be used to install production assemblies into the global assembly cache.

One of the solutions is to use PowerShell to install a DLL into the GAC (Global Assembly Cache) by doing the following

[Reflection.Assembly]::LoadWithPartialName("System.EnterpriseServices") | Out-Null
[System.EnterpriseServices.Internal.Publish] $publish = new-object System.EnterpriseServices.Internal.Publish
$publish.GacInstall(<<FullFilePathToTheDll>>)

This has to do very little with native PowerShell but rather with instantiating and using .NET libraries from PowerShell


After that you need to do an IISRESET in the server

Office 365 Best Practices

Les bonnes pratiques pour Office 365 : La mise à jour de février est disponible

https://channel9.msdn.com/blogs/OfficeDevPnP/Office-365-Developer-Patterns-and-Practices-February-2016-Community-Call

Crawled property does not re-appear after deletion for a custom crawled property

I have deleted a custom crawled property related to a SharePoint column from the Search Administration > Search Schema > Crawled properties

After that,  I performed a full crawl. Once done, I checked crawled properties availability but I did not found the crawled property related to my SharePoint column, that’s the problem.

After some investigations, I discovered that CTS (Content Transformation Service) maintains an in-memory cache of crawled properties.  And on subsequent crawls, it skips properties that are already in the cache. This design is for performance reasons. Since extracting crawled properties and updating them in schema is an intensive operation, CTS is designed this way so that only new crawled properties are crawled on subsequent attempts thus resulting in a much faster throughput in terms of crawl speed.  This design also helps in reducing roundtrips to multiple databases as the property reporter talks to both schema object model and search admin database.

So here’s how to get back the crawled properties.  There are two ways and these can be used as the scenario may be at your environments/deployments.

1. Restart search host controller services.

Open SharePoint 2013 Management Shell in admin mode and issue the command:

Restart-Service spsearchhostcontroller

This will restart all of the search services.

2. The above might not be ideal on environments where all search services are running on single server since it will cause a downtime for all search services (all noderunner.exe will be killed and spawned).  In this case, the specific content processing process can be killed (with a command as shown below) and it will be spawned again immediately.


PS C:\> Get-WmiObject Win32_Process -Filter "Name like '%noderunner%' and CommandLine like '%ContentProcessing%'" | %{ Stop-Process $_.ProcessId }

Get current user groups via CSOM (JavaScript) and REST API

You can find all current user groups in SharePoint using CSOM (JavaScript). Here is the code I used to find groups :

function GetCurrentUserGroups() {

    var clientContext = new SP.ClientContext.get_current();
    this.currentUser = clientContext.get_web().get_currentUser();
    clientContext.load(this.currentUser);

    this.userGroups = this.currentUser.get_groups();
    clientContext.load(this.userGroups);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.OnQuerySucceeded), Function.createDelegate(this, this.OnQueryFailed));
}

function OnQuerySucceeded(sender, args) {
    var g1 = "Visiteurs LMRH"; var g2 = "Visiteurs CASA"; var g3 = "Visiteurs CA";
    var membership = "LMRH";
    var groupsEnumerator = this.userGroups.getEnumerator();
    while (groupsEnumerator.moveNext()) {
        var group= groupsEnumerator.get_current();
        var groupTitle = group.get_title();
        //do something
    }
}

function OnQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

ExecuteOrDelayUntilScriptLoaded(GetCurrentUserGroups, 'SP.js');

You can also use the Rest API to get current user groups and below the code to do that :

function GetCurrentUserGroups()
{
    var requestUrl = _spPageContextInfo.webServerRelativeUrl + '/_api/web/currentuser/?$expand=groups';
    return $.ajax({
            url: requestUrl,
            async: false,
            method: "GET",
            contentType: "application/json;odata=verbose",
            headers: {  
             "Accept": "application/json;odata=verbose"
            }
        });
}

GetCurrentUserGroups()
.done(function(data)
{
    var userGroups = data.d.Groups.results;
    var currentUserGroups = [];
    for(i = 0; i < userGroups.length; ++i){
        currentUserGroups.push(userGroups[i].LoginName);
    }
})
.fail(
function(error){
    console.log(JSON.stringify(error));
});