Tuesday, February 9, 2016

Programmatically upload SharePoint app to a Site collection using feature receiver

Following is a code sample to add SharePoint App to a Site,using a feature receiver. In order to do the task, you should upload the app to the app catalog

private static string IntallApp(Guid currentSiteId)
{
    try
    {
        using (SPSite site = new SPSite(currentSiteId))
        {
            if (null == site.WebApplication.Properties["AppCatalogUrl"])
            {
                return string.Empty;
            }

            //get app catelog url from web application property
            var appCatalogSiteUrl = site.WebApplication.Properties["AppCatalogUrl"].ToString();
            using (SPSite siteApp = new SPSite(appCatalogSiteUrl))
            {
                using (SPWeb webApp = siteApp.RootWeb)
                {
                    SPList appList = webApp.Lists.TryGetList("Apps For SharePoint");
                    SPQuery query = new SPQuery
                    {
                        Query = "<Where><Eq><FieldRef Name=\"Title\" /><Value Type=\"Text\">MyApp</Value></Eq></Where>"
                    };

                    var items = appList.GetItems(query);
                    if (null != items && items.Count >= 1)
                    {
                        SPListItem appCatalogItem = items[0];

                        Guid appProductId = new Guid(appCatalogItem["AppProductID"].ToString());
                        using (SPWeb web = site.RootWeb)
                        {
                            IList<SPAppInstance> existingInstances = web.GetAppInstancesByProductId(appProductId);

                            if (existingInstances.Count > 0) throw new Exception("App is already installed in the target web");

                            //Get the permission XML
                            var appPermissionXml = appCatalogItem["AppPermissionXML"].ToString();

                            //read the client Id from the Permission XML
                            var xmlDoc = new XmlDocument();
                            xmlDoc.LoadXml(string.Format("<Approot>{0}</Approot>", appPermissionXml));
                            var root = xmlDoc.DocumentElement;
                            var clientIdNode = root.SelectSingleNode("//@ClientId");

                            //load the client id, title and stream
                            var clientId = clientIdNode.InnerText;
                            var appItemTitle = appCatalogItem.Title;
                            var appPackageStream = appCatalogItem.File.OpenBinaryStream();

                            //load the principal manager
                            SPAppPrincipalManager manager = SPAppPrincipalManager.GetManager(web);
                            //Check if the app principal is registered in this farm using client ID
                            SPAppPrincipal appPrincipal = manager.LookupAppPrincipal(SPAppPrincipalIdentityProvider.External, SPAppPrincipalName.CreateFromAppPrincipalIdentifier(clientId));
                            //if the principal not found then add
                            if (appPrincipal == null)
                            {
                                //end points  can be blank
                                List<string> endpoints = new List<string>();

                                //app  key
                                SecureString secureString = new SecureString();
                                DateTime now = DateTime.Now;
                                SPAppPrincipalCredential credential = SPAppPrincipalCredential.CreateFromSymmetricKey(secureString, now, now);

                                //create external parameters
                                SPExternalAppPrincipalCreationParameters sPExternalAppPrincipalCreationParameters = new SPExternalAppPrincipalCreationParameters(clientId, appItemTitle, endpoints, credential);
                                sPExternalAppPrincipalCreationParameters.SkipExternalDirectoryRegistration = false;

                                //register the principal
                                appPrincipal = manager.CreateAppPrincipal(sPExternalAppPrincipalCreationParameters);
                            }
                            //load it install in the target web
                            SPAppInstance appInstance = web.LoadAndInstallApp(appPackageStream);

                            //Trust the app
                            SPAppPrincipalPermissionsManager sPAppPrincipalPermissionsManager = new SPAppPrincipalPermissionsManager(web);
                            sPAppPrincipalPermissionsManager.AddAppPrincipalToWeb(appPrincipal, SPAppPrincipalPermissionKind.FullControl);

                            return appInstance.Id.ToString();
                        }
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }

No comments: