Simple way to extract solution and feature details from a sharepoint solution package (wsp)

In my quest to getting a decent SharePoint solution installer sorted and working – one i should say could cater for some of the situations i keep coming across – I finally found a seriously easy solution for how best to extract solution and feature details from the SharePoint solution package (.wsp) – I blogged it earlier on but didn’t immediately find a usable solution.

I then let it lie for a bit, till i took it up again the other week. There was a few other issues that i wanted to change – one was, the ability to actually install several solutions in one go, rather than just one simple one.

i started with a brilliant base platform – the SharePoint Solution Installer found on CodePlex – it had a simple code base (a credit to those that put it together) so it was fairly easy to get my plans hooked in to this one app.

Now, should just say that i’m not quite finished with it yet – will upload it when i’m done though.

Anyways – a .WSP file is essentially a .CAB file – actually, it’s a .CAB file – you rename it and it behaves exactly like a .CAB file and i needed to extract the files in it and locate the details i required.

so i looked around for smart people that’s already figured this one out – and voila, Live Search finally delivered what i needed.

CodeProject: Iterate and Extract Cabinet File – my savior as i really didn’t want to have to go through all of the hassle myself if somebody else had figured it out already.

So, simple it was – got things rolling and here’s how easy it was to implement the extraction of the .WSP file.

   1: private TCabinetFile _cabinetFile = new TCabinetFile();
   2: private Dictionary<string, TFile> _fileList = new Dictionary<string, TFile>();
   4: private void btnSelect_Click(object sender, EventArgs e)
   5: {
   6:     var _dialog = new OpenFileDialog
   7:                       {
   8:                           Filter = "Solution Files (*.wsp)|*.wsp",
   9:                           InitialDirectory = @"C:\",
  10:                           FilterIndex = 0
  11:                       };
  13:     if (_dialog.ShowDialog() == DialogResult.OK)
  14:     {
  15:         _cabinetFile.FileFound += _cabinetFile_FileFound;
  16:         _cabinetFile.IgnoreInsidePath = false;
  17:         _cabinetFile.Name = _dialog.FileName;
  19:         if (_fileList.Count > 0)
  20:         {
  21:             foreach (var _file in _fileList)
  22:             {
  23:                 _cabinetFile.Extract(_file.Value);
  25:                 ExtractFeatureDetails(_file);
  26:             }
  27:         }
  28:     }
  29: }

Just create the OpenFileDialog control and select the .WSP file – then wire up the TCabinetFile’s FileFound event, set the name of the TCabinetFile to the file selected in the OpenFileDialog.

   1: void _cabinetFile_FileFound(object sender, EventArgs e)
   2: {
   3:   var _file = sender as TFile;
   4:   if (!_file.Name.ToLower().Equals("feature.xml", StringComparison.Ordinal)) return;
   6:   _fileList.Add(string.Format("{0}{1}", _cabinetFile.OutputDirectory, _file.FullName), _file);
   7: }

Since i’m only interested (at this stage) in the feature.xml file(s) we’ll only locate those in the cabinet file.

   1: private void ExtractFeatureDetails(KeyValuePair<string, TFile> _file)
   2: {
   3:     var _xelm = XElement.Load(_file.Key);
   5:     var _elements = from elm in _xelm.DescendantsAndSelf()
   6:                    select elm;
   8:     foreach (var _element in _elements)
   9:     {
  10:         if (string.Equals(_element.Name.LocalName, "Features"))
  11:         {
  12:             //get solution details and feature details
  13:             //_element.Attribute("SolutionId").Value;
  14:             //_element.Attribute("Title").Value;
  15:             //_element.Attribute("Scope").Value;
  16:             //_element.Attribute("Version").Value;
  17:         }
  18:     }
  20:     if (File.Exists(_file.Key))
  21:     {
  22:         File.Delete(_file.Key);
  23:     }
  24: }

Anyways – as with all software development, there’s thousands and thousands of ways to skin a cat – so i took the easy way out and got only of the CabinetFile (on CodeProject) project, did a few modifications (not essential to this) and voila..

a simple and easy solution on how to get these details from the .WSP file.

Now, i’d be interested to see what other people have done – who knows, might be there’s an even easier way to do it?