A couple of weeks ago, I had the worst professional SharePoint moment of my life, thanks to SharePoint 2007, Visual Studio 2008, and WSPBuilder. Deploying custom solutions to SharePoint is something I have done many times, but I’ve learned to expect nothing but the worst, especially when the task at hand seems like it should be easy. In the end, I had wasted far too much time performing a seemingly mundane task. My goal is to relay this experience and how I overcame it, in the hopes of saving several hours of your life.
Using Visual Studio 2008 and WSPBuilder, I had created a custom Workflow solution to deploy to a SharePoint 2007 site. The workflow was a fairly simple one, simply copying a document from a drop-off library to a document library on a different site collection, along with its associated metadata. Using a stand-alone installation of SharePoint 2007 on a virtual machine, I created a model of the production site, based on my understanding of the architecture. Then I proceeded to write a workflow to fit this design.
After writing the code and creating the .wsp, the initial deployment to production went without a hitch. However, after some quick testing, it was clear a couple minor tweaks needed to be made to the workflow; my development site did not quite match the production environment. In retrospect, I would say this is where things began to go wrong. But at the time, this seemed like no big deal. It should be easy to tweak the workflow code and redeploy it. Right?
Unfortunately, I’ve never been so wrong. After making the code changes, I created a new .wsp, retracted and removed the old solution from SharePoint, and deployed the new solution. I tested the workflow again, and, to my bewilderment, it still did not work correctly. In fact, it didn’t seem to be behaving any differently than the first time.
I went back over my code to see if I made any silly mistakes. Everything looked good as far as I could tell, and unfortunately in this situation, I could not debug my solution on the production server. My only option was to change the code and redeploy. After making minor code changes and redeploying several times, nothing I did seemed to make a difference. The workflow seemed to run exactly the same each and every time, returning what seemed like the same error in the same place.
So I began to think about it a little differently. It almost seemed to be using the original DLL in the GAC (Global Assembly Cache), even though I obviously had retracted the old one and deployed a new one. The GAC is a cache, after all. Just to be sure, I navigated to the GAC in Windows Explorer at C:\Windows\assembly, and sure enough, the DLL was not listed in there after retracting the solution. And when I deploy the new solution, the DLL would show up. It seemed to be working exactly as I would expect.
One thing I did notice was that the assembly version was still 184.108.40.206. Perhaps since I left the assembly version the same in Visual Studio, the GAC wasn’t taking the new DLL at all? To change the DLL version, I had to change it in 3 spots in Visual Studio: in the project properties pages, in the elements.xml file, and in the feature.xml file. After making this change, I packaged up the .wsp again, and deployed it, confident my nightmare was nearing its end.
This time, SharePoint did not seem to recognize my new feature at all, as I could not find it in the site collection features list to activate it, or see the workflow in the list of available workflows to add to a list. After Googling my issue, I decided that I may benefit from using STSADM exclusively for adding, deploying, and installing solutions and features. Previously, I had been simply adding it with STSADM, and then using Central Admin to deploy the solution and activate it. This approach, in my experience, has appeared to work flawlessly with SharePoint 2010, but apparently this is not the case for SharePoint 2007.
It turned out that while I had updated the solution to a new version, the feature was still looking for the old version. This is where extensive use of stsadm came in to play. Using the command prompt, I issued these commands, in order:
- stsadm –o deactivatefeature –name <name of feature folder> –url <URL of SharePoint web application>
- stsadm –o uninstallfeature –name <name of feature folder> –force
- stsadm –o retractsolution –name <name of solution .wsp file> –immediate –allcontenturls
- stsadm –o deletesolution –name <name of solution .wsp file>
- stsadm –o addsolution –filename <file path to .wsp file>
- stsadm –o deploysolution –name <name of solution .wsp file> –immediate –allowgacdeployment –url <URL of SharePoint web application>
- stsadm –o installfeature –name <name of feature folder> -force
- stsadm –o activatefeature –name <name of feature folder> –url <URL of SharePoint web application> -force
Using stsadm –o updatesolution probably would have worked as well, but that is not the route I ended up taking. Finally, I tested the workflow one last time, and it worked like a charm. After wasting many hours of my life on something that seemed so simple, I was relieved to have this nightmare behind me. Hopefully this will help prevent you from experiencing the same problem.
As I mentioned before, I probably could have saved a lot of headache if I had a better understanding of the production site’s architecture before I began development. It is important to ask the right questions in order to get the answers you need. The person you are getting the information from won’t always know all of the important details, so it is up to you, as the architect and developer, to get the information you need to get the job done.
If you want to learn more about WSPBuilder or STSADM, please check back here soon. I plan on covering both of these useful tools in the near future.Image Courtesy: Brian Pennington