Deploying Apps with the Application Model

Deploying Apps with the Application Model

One of the new capabilities of SharePoint 2013 is the use of Apps, and you can get your apps from the Office Store or build them yourself. If you are considering the Application Model for repeatable and structured deployments one of the things you are most likely to encounter is the wish to automate the process of installing and configuring apps.

The Application Model allows for options to automate this process and use code to add and activate your apps, however this can only be achieved if you have the actual App Package. If you do not have the App Package it will not be possible to download the App from the Office Store. Besides that if you have an App Package there will be no link to the Office Store and thus you will not be able to get updates. So using the Application Model to deploy apps will only be a valid option if you have your own App Packages.

In order to use the Application Model to install Apps you will have to enable sideloading. From within the context of SharePoint App sideloading is the ability to install a SharePoint app directly into a site. By default sideloading is only enabled on a developer site and not activated on any other site. The official statement MSDN on sideloading is:

Warning: Sideloading apps is a developer/test feature not intended for production use.
Do not sideload apps regularly, or keep app sideloading enabled for longer than you are actively using the feature!

You can easily check if sideloading is enabled on a sitecollection:

var appSideloadingEnabled = AppCatalog.IsAppSideloadingEnabled(clientContext);
clientContext.ExecuteQuery();

if (appSideloadingEnabled.Value) {
    // sideloading enabled 
}
else {
    // sideloading not enabled 
}

If sideloading is not enabled you can activate it using a feature, if it is enabled you can delete the same feature to make sure it is disabled.

Guid EnableAppSideloadingFeatureId = new Guid("AE3A1339-61F5-4f8f-81A7-ABD2DA956A7D");

if (sideloadingEnabled) {
    site.Features.Remove(EnableAppSideloadingFeatureId, false);
}
else {
    site.Features.Add(EnableAppSideloadingFeatureId, false, FeatureDefinitionScope.Farm);
}

clientContext.ExecuteQuery();

Once sideloading is enabled you can add a new app package. If you have the app package all we need is a stream and some logic in place to validate if the install is succeeded.

Guid appId = Guid.Empty;
Stream package = null;
string appinstallUrl = HostingEnvironment.MapPath(string.Format("~/{0}", "AppInstalls/Mavention.SharePoint.BirthdayApp.app"));

try {
    AppInstance appInstance = web.LoadAndInstallApp(System.IO.File.OpenRead(appinstallUrl));
    clientContext.Load(appInstance);
    clientContext.ExecuteQuery();

    if (appInstance != null && appInstance.Status == AppInstanceStatus.Initialized) {
          while (appInstance.Status == AppInstanceStatus.Initialized) {
            System.Threading.Thread.Sleep(500);

            clientContext.Load(appInstance);
            clientContext.ExecuteQuery();

            // Finished installing 
            if (appInstance.Status == AppInstanceStatus.Installed) {
      		appId = appInstance.Id;
                break;
            }
            // Installing fails
            if (appInstance.Status == AppInstanceStatus.InvalidStatus) {
                throw new ArgumentException("App Install failed");
            }
        }
    }
}
finally {
    if (package != null)
        package.Close();
}

Once your package is installed in the App you can of course disable sideloading if you are no longer using it. However once the app is installed it does not have the required permissions. If you install an app through the UI it will get redirect automatically to the page allowing you to configure it’s permissions. Unfortunately it is not possible to this from a code perspective, and the only option you have is to construct a redirect URL so that your user can set the corrected permissions.

The default location to set these permissions is at /_layouts/15/AppInv.aspx?Manage=1&AppInstanceId=ID, so we can construct a redirect to that page if the app is installed. To do that you will need the appId and make sure that it only redirects if the app has been successfully installed. Keep in mind that in order to use the Site.Url property it needs to be initialized.

if (!string.IsNullOrEmpty(appId)) {
	Response.Redirect(string.Format("{0}/_layouts/15/AppInv.aspx?Manage=1&AppInstanceId={1}&Source={2}", clientContext.Site.Url, appId, HttpContext.Current.Request.Url.AbsoluteUri));
}

As you can see there are some options to deploy apps by using the Application Model however it is far from ideal and in most cases will not be sufficient for a production environment.

You can download the Sample App for SharePoint (451KB, ZIP).

Leave a Reply