How to upload and activate sandbox solutions using CSOM

I was working with one my friends, Suman (shoe) Chakrabarti on a Patterns & Practice solution that prevents deletion of sites using partial code (Sandbox). Well he wrote the code for that, but we decided to add an extra bonus item. We thought it would be nice to show how to add the solution to the gallery and active the solution in the sample. 

Solution Deployment/Removal

In order to upload the wsp to the Solution Gallery, we are going to use  the FileCreationInformation class to upload the file to the gallery. Removing the solution is handled by finding the uploaded file and calling the DeleteObject member.

// get the file from the server path in the provider site

var filePath = Server.MapPath("~/PreventDeleteSites.wsp");

var file = new FileStream(filePath, FileMode.Open);

// create the FileCreationInformation object and prepare

// to upload it to the solution gallery

var fileCI = new FileCreationInformation() {

    ContentStream = file,

    Url = "PreventDeleteSites.wsp",

    Overwrite = true

};

// upload the solution to the gallery

var uploadedFile = solutionGallery.RootFolder.Files.Add(fileCI);

clientContext.Load(uploadedFile);

clientContext.ExecuteQuery();

Solution Activation/Deactivation

Solution activation is done using the DesignPackage class in the Microsoft.SharePoint.Client.Publishing assembly.  We are going to use the DesignPackage.Install and DesignPackage.Uninstall members to activate and deactivate the solution for the site collection.

// get the DesignPackageInfo (which is the same name for a sandbox solution)

var wsp = new DesignPackageInfo(){

    // during deployment, the solution ID is not necessary but we need the Guid during removal

    PackageGuid = Guid.Empty, // 4c16c0b9-0162-43ad-a8e9-a4b810e58a56

    PackageName = "PreventDeleteSites"

};

// install the solution from the file url

var filerelativeurl = solutionGallery.RootFolder.ServerRelativeUrl + "/PreventDeleteSites.wsp";

DesignPackage.Install(clientContext, clientContext.Site, wsp, filerelativeurl);

clientContext.ExecuteQuery();

References

The Prevent Site Deletion sample that shows this code in action

Office 365 Patterns and Practices

Microsoft.SharePoint.Client.Publishing