Showing posts with label WSPBuilder. Show all posts
Showing posts with label WSPBuilder. Show all posts

Thursday, November 25, 2010

Build and deploy Sharepoint solutions using bat functions

Today for solution administration in Sharepoint we can use great opportunities of PowerShell. However there is interesting feature available in simple cmd (or bat) files which can be used in every day development – bat functions. Of course it is not so powerful as PowerShell, but is it very simple and doesn’t require any additional components in the system. We used this approach in several projects in conjunction with WSPBuilder and it proofed its reliability and value. If you don’t familiar with this concept you can check this link for example: Routines functions methods in .bat.

Assume that you have several class library projects (e.g. Project1 and Project2) in Visual Studio which are built into separate wsp packages using WSPBuilder. Project1 doesn’t contain web application specific resources and should be deployed globally. Project2 in contrast contains web application specific resources and should be deployed into particular web application. You need to automate build process. In order to do that you can use the following cmd file which uses bat functions technique:

   1: @cd ..
   2:  
   3: @call :install Project1 global
   4: @call :install Project2
   5:  
   6: @pause
   7: @exit
   8:  
   9: rem Makes wsp package, add it to solution store, deploys it and waits some time in order to allow sharepoint successfully install wsp
  10: :install
  11: @cd %1
  12:  
  13: @call :create_wsp %1
  14:  
  15: @call :add_solution %1
  16:  
  17:  
  18: @if "%2" == "global" (
  19:     @call :deploy_solution_globally %1
  20: ) else (
  21:     @call :deploy_solution_web_specific %1
  22: )
  23:  
  24: @call :delay 5
  25:  
  26: @cd ..
  27: @exit /b
  28:  
  29:  
  30: rem Creates wsp based on current directory
  31: :create_wsp
  32: wspbuilder -BuildWSP true -ResetWebServer true -TraceLevel Warning
  33: @exit /b
  34:  
  35:  
  36: rem Adds wsp file in the current directory to solution store
  37: :add_solution
  38: stsadm -o addsolution -filename %1.wsp
  39: @exit /b
  40:  
  41:  
  42: rem Deploys wsp from current directory to specific web applications (i.e. not globally)
  43: :deploy_solution_web_specific
  44: stsadm -o deploysolution -local -allowgac -allcontenturls -name %1.wsp
  45: @exit /b
  46:  
  47:  
  48: rem Deploys wsp from current directory globally
  49: :deploy_solution_globally
  50: stsadm -o deploysolution -local -allowgac -name %1.wsp
  51: @exit /b
  52:  
  53:  
  54: rem Delays execution
  55: :delay
  56: @echo Off
  57: PING -n %1 127.0.0.1>nul
  58: @echo On
  59: @exit /b

I added comments to the script so it is more or less self descriptive. Note that every function begins with colon “:” and ends with “@exit /b” command which returns execution to the caller. So we call “install” function for Project1 and Project2. What “install” function does? First of all it creates wsp package using wspbuilder (see “create_wsp” function). After that it adds solution to the solution store (“add_solution” function) and deploys solution to the server. Note that for Project1 we specified additional param “global” which is used in the code in order to determine how solutions should be deployed – globally (“deploy_solution_globally” function) or web application specific (“deploy_solution_web_specific”).

After solution is deployed “install” function waits some time in order to give Sharepoint time to proceed the request. Note how “delay” function is implemented: it uses “-n” parameter of well known “ping” command in order to wait specified amount of seconds

That’s how this feature can be used in Sharepoint development to automate simple scenarios using common cmd files. Of course for more complicated things you should prefer PowerShell, however for many real world cases described technique can be useful as well.

Thursday, September 30, 2010

Quick way to determine processes which use dll assembly

In every day Sharepoint development we often need to update assemblies in GAC via WSPBuilder. Sometimes (especially if you use ReSharper) you will see access denied exception which is caused by the fact that assembly being updated is locked by another process:

   1: WSPBuilder AddIn Error
   2: System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
   3:    at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   4:    at System.GACManagedAccess.AssemblyCache.InstallAssembly(String assemblyPath, InstallReference reference, AssemblyCommitFlags flags)
   5:    at WSPTools.VisualStudio.VSAddIn.Library.Commands.CopyToGAC.Execute()
   6:    at WSPTools.VisualStudio.VSAddIn.VSMenuHandler.Execute(String commandName)
   7:    at WSPTools.VisualStudio.VSAddIn.Connect.Exec(String commandName, vsCommandExecOption executeOption, Object& varIn, Object& varOut, Boolean& handled)

Sometimes adding assembly 2nd time solves the problem, sometimes not. In the last case you need to determine what process blocked your assembly. In order to do it you can use GUI procexp utility (Ctrl+F to find dlls attached to process) from Sysinternals. There is also built-in Windows utility tasklist which allows you to find what processes use specified dll assembly:

   1: tasklist /m myassembly.dll
   2:  
   3: Image Name                     PID Modules
   4: ========================= ======== ============================================
   5: devenv.exe                    2332 myassembly.dll
   6: w3wp.exe                      2892 myassembly.dll

This little tip may help you not only in Sharepoint development as well.