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)
        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();
                        return string.Empty;
    catch (Exception ex)
        throw ex;

No comments: