Pages

Showing posts with label Deployment. Show all posts
Showing posts with label Deployment. Show all posts

Saturday, June 16, 2012

SharePoint: Package your external dependencies to another solution

Sometimes we use some third party tools that create external dependencies to our SharePoint projects. For example if you use Pattern and Practice SharePoint Guidance Library in your SharePoint project in visual studio and build WSP, then  WSP package will include these SharePoint Guidance libraries also. However, this might create problems related to deployment. To explain the issue, let’s consider how SharePoint solution retraction/removal might affects other WSP package deployed in the same SharePoint environment.

 

Scenario: Two WSPs sharing Common Dependency

Let’s consider you have two Visual studio SharePoint project: SharePoint Project 1 and SharePoint Project 2. Both projects are using (i.e., referencing) a third party dll (i.e., thirdparty.dll). Now if you generate WSP from two different Visual Studio projects, both WSP will include the thirdparty.dll in their WSP package.

image

Figure 1: A single thirdparty.dll is shared by two WSP solutions

 

As shown in the image above, a single third party dll is referenced by two Visual studio SharePoint projects. Now when you 'will build two different WSP solutions the same third party dll will be included to two different WSPs. If these two WSPs are deployed in a single SharePoint server/farm with GAC deployment, then both WSP will deploy the same ThirdParty.dll in the GAC. Everything will work fine till now.

 

Problem: retracting/removing one solution will fail other WSP to work

Now consider a scenario. After deploying the two WSPs in the production with GAC deployment, you have found a problem with Project 2 WSP. So you want to remove the Project 2 WSP while you will keep Project 1 WSP. So you will remove the Project 2 WSP. Removing the Project 2 WSP will remove all the assemblies from GAC/BIN related to the WSP. So removing the Project 2 WSP will remove thirdparty.dll from GAC. As soon as you remove the Project 2 WSP from SharePoint server/farm, Project 1 WSP will fail to work as it’ll not find the referenced thirdparty.dll in GAC. So removing Project 1 WSP (or project 2 WSP) will remove the thirdparty.dll from GAC and other WSPs which are using the same dll will fail to work.

 

Solution: Package your external dependency to new WSP

The solution to this problem is to exclude thirdparty.dll from both WSPs and create a new WSP dependency/prerequisite solution for thirdparty.dll. You can do it easily with SharePoint 2010 Package editor. As a result the thridparty.dll will not be included in any of the two WSPs.To package a new WSP for the thirdparty.dll you need to create another new Visual Studio SharePoint projects which will just include the thirdparty.dll (or any other prerequisites). The new architecture is shown below:

image

Figure 2: Shared thirdparty.dll is included in separate WSP

 

As shown in the figure 2, now the shared dll (thirdparty.dll) is excluded from Project 1 and Project 2 WSP. Whether you use WSPBuilder or SharePoint 2010 project template in Visual studio, you can exclude one more dlls from the WSP. Then create a new Visual Studio project (WSPBuilder or SharePoint) which will include the thirdparty.dll and the output WSP package will include the shared/external dll. Now you will have three WSPs and the new WSP will be prerequisite WSP for other two WSPs.

Now with this model, you can remove Project 1 WSP or Project 2 WSP from your server without affecting each other. Even if you remove Project 1 WSP from the Farm/Server, the thirdparty.dll will not be removed from GAC as it’s not deployed as part of Project 1 WSP. Later if you want to redeploy the Project 1 WSP again then you don’t need to redeploy the prerequisite WSP as it’s already deployed in the server. If needed you can package your external dependency in more than one WSP packages.

 

Conclusion

If you are developing a SharePoint custom product that will be deployed in some client’s environment, then you should care about creating one or more dependency WSP packages. If your SharePoint solution is developed for a specific client or as an in-house product then you might not face the problem even if you don’t create a prerequisite WSP package. However if you are developing a SharePoint solution as a custom product and you don’t know the client yet, you should create prerequisite WSP package. And then when you will deploy your product in client server, you can deploy the perquisite or not depending on if the client has the prerequisite dlls install or not. If the client has the dlls/prerequisites installed in the farm, you don’t need to deploy the prerequisite WSP. This will make your SharePoint product more independent and will have less impact on other SharePoint solution deployed in the farm.

Thursday, February 17, 2011

IE9 and User Agent String

With new IE in market the web developer community has been in the danger of supporting another extra browser. Recently we have found our application is in problem with IE9. We have a client application that put some data in User Agent Post platform value in registry. From IE6 to IE8 the post platform value was passing from server to client in UserAgent. So basically we had put some value in UserAgent Post Platform in registry from a client application and from our web application we had found the value (as the post platform values are passed in User Agent from IE6 to IE8). But with IE the post platform values are not passed with User Agent automatically.

 

User Agent and Pre/Post Platform value

If you are interested on how the Pre and Post Platform values works with User Agent you can visit the MSDN link: http://msdn.microsoft.com/en-us/library/ms537503%28VS.85%29.aspx

 

IE9 introduces Default User Agent and Extended User Agent

In IE9 the user agent has been divided into two parts:

Default User Agent (UA): IE9 by default will not send the pre/post platform values from client to server. So if you have some values in client’s pre and post platform then your web site will not get those values (from pre and post platform) as IE9 will not pass those values to server. However IE6 to IE8 will work as usual (i.e., pass those pre and post platform values) .

Extended User Agent (UA): So the question is if IE9 doesn’t send the pre and post platform values by its own then how can we access the platform values? The answer to this question is simple but implementation is tricky. You can get the pre and post platform values on client side only with JavaScript by accessing Navigator.UserAgent. So IE9 will not take the responsibility of passing Extended UA from client to server. You need to do it by your own. You need to read the extended UA by javascript on the client side and need to pass to the server by using Hidden control or any other way.

 

How to get the Pre/Post platform vales IE9?

By following javascript code you can get the pre/post platform values on client side.

<script type="text/javascript">
    alert(navigator.userAgent);
</script>

You can get more details on this on MSDN IE blog: http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx

Sunday, November 7, 2010

SharePoint Restore Error: Your backup is from a different version of Microsoft SharePoint Foundation and cannot be restored to a server running the current version. The backup file should be restored to a server with version '14.0.0.5050' or later.

I had needed to move my dev environment from one Virtual machine to another. So I took backup from source server and tried to restore the backup in new server. However, I have got the error “Your backup is from a different version of Microsoft SharePoint Foundation and cannot be restored to a server running the current version. The backup file should be restored to a server with version '14.0.0.5050' or later.” I was totally confused as I had the same version of SharePoint in both server. Then I double checked the version and it was 14.0.4762.1000 for both servers.

Getting confused I googled and found that solution. This is a bug which is fixed by SharePoint 2010 August cumulative update. The updates are available in the following link:

 

After installing the updated the error gone…

Tuesday, September 21, 2010

SharePoint 2010: Change the default Feature installation location from Visual Studio

In SharePoint 2007, we used to put the custom features in folder “12\TEMPLATE\FEATURES”. In SharePoint 2010, feature management is mostly done by Visual Studio 2010 UI. We mostly don’t care where the features are installed. However, with surprise I noticed that the feature is installed in the Features folder but not directly under the Features folder. Visual Studio creates a new folder under “14\TEMPLATE\FEATURES” folder and copy the features under that new folder.The name is in the format “VisaulStudioProjectName_FeatureName”. The name comes from feature’s properties and you can change the format. The following image shows the feature properties defining the naming format.

image

Figure 1: Feature deployment path in properties window

Now if you want to put the features just directly under the ‘14\Template\Feature’ folder, then just the set the ‘Deployment Path’ property value to '

$SharePoint.Feature.FileNameWithoutExtension$

 

Maybe sometimes you want to install the feature just under Features folder and in that case changing the deployment path will be helpful.

Tuesday, June 15, 2010

Execadmsvcjobs alternative in SharePoint 2010. Run job immediately

In sharePoint 2007, whenever we needed to ensure that any pending jobs are not there we were used to run the following command. One scenario where we needed this command is when you have deployed a solution to a web or retract solution from web application. In these case, SharePoint doesn’t deploy or retract solution immediately rather creates jobs. So if want to run any command that depends on solution deployment then you need to run the following command to make sure there is no pending jobs.

stsadm –o execadmsvcjobs

However in SharePoint 2010, stsadm is kind of dead. So if you now need to deploy a solution and then activate feature, then after running solution deployment command you need to make sure that the solution deployment job is executed before activating/installing feature. I have found a concept in the link: http://msdn.microsoft.com/en-us/library/ff459292.aspx. I have modified the code a bit to generate the following PowerShell function. Passing a solution name in the function, check if the solution job is finished or not. If not finished then the function waits for the solution deployment job to finish.

function WaitForJobToFinish([string]$SolutionFileName)
{ 
    $JobName = "*solution-deployment*$SolutionFileName*"
    $job = Get-SPTimerJob | ?{ $_.Name -like $JobName }
    if ($job -eq $null) 
    {
        Write-Host 'Timer job not found'
    }
    else
    {
        $JobFullName = $job.Name
        Write-Host -NoNewLine "Waiting to finish job $JobFullName"
        
        while ((Get-SPTimerJob $JobFullName) -ne $null) 
        {
            Write-Host -NoNewLine .
            Start-Sleep -Seconds 2
        }
        Write-Host  "Finished waiting for job.."
    }
}

In my another blog http://ranaictiu-technicalblog.blogspot.com/2010/05/sharepoint-2010-deployment-powershell.html I have described the in details on how to use the function.

Tuesday, May 11, 2010

SharePoint 2010 Deployment: Powershell Script

Pre-SharePoint 2010 developers are familiar with Stsadm command. The general scenario of SharePoint 2007 deployment is to develop a batch file with stsamd commands. A generic deployment includes the following steps:
  • Deactivate Features
  • Uninstall Features
  • Retract Solution
  • Delete Solution
  • Add Solution
  • Deploy Solution
  • Install Features
  • Activate Features

SharePoint 2007 Deployment Script:

I’ll first describe how stsadm command file looks like implementing the above steps. You can put the following script in a batch file and then clicking on the batch file in SharePoint server, will deploy the solution. The solution and the batch file need  to be in the same folder. The first line of the script (cd /d %~dp0) will change the current directory to the script directory.
--Change script directory to current directory 
cd /d %~dp0 
@SET STSADM="c:\program files\common files\microsoft shared\web server extensions\12\bin\stsadm" 
@SET SITEURL="http://localhost" 

echo Deativating 'MyFeature' feature. 
%stsadm% -o deactivatefeature -name MyFeature -url %SITEURL% -force  
echo Uninstalling 'MyFeature' feature. 
%stsadm% -o uninstallfeature -name MyFeature -force  

echo Retracting solution 'MySolution.wsp' 
%stsadm% -o retractsolution -name MySolution.wsp -immediate -allcontenturls %stsadm% -o execadmsvcjobs  
echo deleting solution 'MySolution.wsp' 
%stsadm% -o deletesolution -name MySolution.wsp -override  

echo adding solution 'MySolution.wsp'
%stsadm% -o addsolution -filename MySolution.wsp  
echo deploying solution 'MySolution.wsp' 
%stsadm% -o deploysolution -name MySolution.wsp -url %SITEURL% -immediate -allowGacDeployment -force 
%stsadm% -o execadmsvcjobs 
 
echo Installing 'MyFeature' feature. 
%stsadm% -o installfeature -name MyFeature -force  
echo activating 'MyFeature' feature. 
%stsadm% -o activatefeature -name MyFeature -url %SITEURL% -force  
iisreset /restart /noforce /timeout:60 
File: SharePoint 2007 Script for Deployment

PowerShell Scripting Basic, every SharePoint Developer Should Know

In SharePoint 2010 stsadm is supported but powershell commands are recommended to use. To know how to run SharePoint powershell script, let’s get an overview of PowerShell. I’ll try to provide a gist on Powershell so that you can write your own Script for SharePoint. As as SharePoint developer we don’t need to be expert in PowerShell script but we need to know the basic syntax.
 PowerShell command format: Powershell command has two parts: verb and noun. For example, to get current date, you need to execute command get-date. Here get is verb then a hyphen(-) and finally date which is noun. Powershell is not case sensitive. But its good practice to use Caml case in command. The following command uses verb-noun format to get current date.
Get-Date
Get Help on PowerShell Command: To get help for a command you can use Get-Help command. The following command is used to get help on Get-Date:
Get-Help Get-Date
You can even type the verb part including hyphen and then press tab. You’ll then get the all commands starting with the verb.
PowerShell command execution Permission: Before you execute any command, you need to enable PowerShell to execute command. You can get the current execution policy by running the following command:
Get-ExecutionPolicy
The result of the command might be one of the followings:
  • Restricted
  • AllSigned
  • RemoteSigned
  • Unrestricted
  • Bypass
  • Undefined
To execute command or run scripts, you can set execution policy to ReomteSigned but based on your security consideration, you can use different options. To set execution policy, you can run the following command:
Set-ExecutionPolicy RemoteSigned
Run a PowerShell Script: To run a PowerShell script, you need put the file name in the PowerShell command prompt. But there are few conventions/restrictions that you need to follow.
  • To run a script file you need to type complete path of the script file. The complete path may be in the form ‘.\folder\subfolder\script.ps1’ or a full path like ‘c:\folder\subfolder\script.ps1’
  • To execute a script you need to use the format of & ScriptPath format. If the file path has space then use double quotation to enclose the path. So to execute a file you can use the command like below:
& “C:\My Scripts\Script.ps1”
  • If you want to run PowerShell script from Run window then you can do so by putting the following command in Run window:
Powershell –NoExit & ‘C:\My Scripts\Scripts.ps1’
One thing to remember in the above script is that single quote is used instead of double quote when you will run the above command from Run window. Single quote must be used for file path if the file path has space. Double quote will not work in this case.
  • Variables in PowerShell are identified by putting a  $ prefix. You’ll find how the variable is used in the section “A Sample PowerShell Script”
  • PowerShell script file is saved with extension .ps1
A Sample PowerShell Script:
Let’s say you have a PowerShell script (as shown below) in a file named script.ps1. Now You want to run the following powershell script (in a file Script.ps1) from Run window. The script will add two numbers and print the output.
echo 'setting a value for a'
$a=5
echo 'setting a value for a'
$b=3
echo 'adding a and b'
$c=$a+$b
echo "reslut is $c"


The variables in the above script are prefixed by $. Take a close look at the last echo. The echo has a $c in the double quotation. Remember, you can refer a variable name in double quotation string (as in the last echo in the above script). But the same is not true for single quote. If you would use the $c inside single quote then it would print back the $c. Single quote is considered as literal string in PowerShell.

SharePoint 2010 Deployment

In SharePoint 2010, you can use PowerShell script for deploying SharePoint solution/features. Let’s first take a look at how the deployment script will look like
PowerShell Deployment Script: Deployment in SharePoint 2010 still has the same eight steps (Deactivate Features, Uninstall Features…..) as described at the beginning of this post. The following script deploy a solution:
function WaitForJobToFinish([string]$SolutionFileName)
{ 
    $JobName = "*solution-deployment*$SolutionFileName*"
    $job = Get-SPTimerJob | ?{ $_.Name -like $JobName }
    if ($job -eq $null) 
    {
        Write-Host 'Timer job not found'
    }
    else
    {
        $JobFullName = $job.Name
        Write-Host -NoNewLine "Waiting to finish job $JobFullName"
        
        while ((Get-SPTimerJob $JobFullName) -ne $null) 
        {
            Write-Host -NoNewLine .
            Start-Sleep -Seconds 2
        }
        Write-Host  "Finished waiting for job.."
    }
}

Add-PsSnapin Microsoft.SharePoint.PowerShell
 
$CurrentDir=$args[0]
$solutionName="Limeco.UI.WebParts.wsp"
$SolutionPath=$CurrentDir + "\"+$solutionName 
 
Write-Host 'Going to disable feature'
disable-spfeature -identity Limeco.UI.WebParts_LimecoWebPartFeature -confirm:$false -url http://localhost
 
Write-Host 'Going to uninstall feature'
uninstall-spfeature -identity Limeco.UI.WebParts_LimecoWebPartFeature -confirm:$false -force
 
Write-Host 'Going to uninstall solution'
Uninstall-SPSolution -identity $solutionName  -allwebapplications -confirm:$false

Write-Host 'Waiting for job to finish'
WaitForJobToFinish 

Write-Host 'Going to remove solution'
Remove-SPSolution –identity $solutionName -confirm:$false
 
Write-Host 'Going to add solution'
Add-SPSolution $SolutionPath
 
Write-Host 'Going to install solution to all web applications'
Install-SPSolution –identity $solutionName –Allwebapplications –GACDeployment

Write-Host 'Waiting for job to finish' 
WaitForJobToFinish 

Write-Host 'Going to enable Feature' 
Enable-spfeature -identity Limeco.UI.WebParts_LimecoWebPartFeature -confirm:$false -url http://localhost 

Remove-PsSnapin Microsoft.SharePoint.PowerShell
File: Myscript.ps1

The first thing in the above script is a function WaitForJobToFinish which is used to make sure jobs are finished executing before moving on. This method is similar like the command ‘stsadm –o execadmsvcjobs’ in SharePoint 2007. In the above script, the line ‘Add-PSSnapin’load the SharePoint PowerShell script. If you already using SharePoint 2010 Management Shell (Which is a PowerShell extension already) then this line should be removed. In the above script Write-Host is just like print function that print a string in the console. FYI, when you pass arguments to an PowerShell script, the arguments are kept in a PowerShell variable $Args. You can access any arguments by assessing it $Args[index]. I think the command in the above script is self-explanatory. The –confirm:$false is for not to prompt user for confirmation. In the above script you need to pass the solution directory.
Automate the Deployment Script: To automate the powershell Script you need to put the above script in a PowerShell scipt file(having ps1 extension). Let’s say you have you script in a file named as myscript.ps1. Now you need to run the script you need a batch file which will execute the script file. The script file may be like one shown below:
cd /d %~dp0
powershell -noexit -file    ".\MyScript.ps1" "%CD%"

 File: MyCommand.bat
In the above command, the first line change the current directory to the location from where the batch file is run. Then I have run the PowerShell with the MyScript.ps1 file and passed the current directory as argument (%CD%)

Conclusion

I think stsadm command was simple and easy to use. PowerShell is too much powerful and extensible. You can do almost all kinds of SharePoint programming with PowerShell script. My personal view is that we, SharePoint developers, don’t need to be expert in PowerShell but we need to have basic knowledge of “How to use PowerShell Script for SharePoint Deployment/Maintenance?”. There are already much activities on web around PowerShell and SharePoint. Few useful links related to PowerShell and SharePoint are given below:
Some Useful CodePlex links:
Here is a Visual Studio 2010 extension for SharePoint PowerShell Scripting:
Here is a tool called PowerGui that is handy for editing PowerShell script:

The concept for waiting for job to finish, I have taken from the following link:
http://msdn.microsoft.com/en-us/library/ff459292.aspx

Friday, May 7, 2010

Content Migration from SharePoint 2010 Beta to RTM is not supported

If anyone out there has already developed some SharePoint sites with beta release and now want to move to RTM then there’s a bad news. The migration is not supported. If you try to move your content with Content Migration API then you’ll get an error message like below:

The Version of the package 14.0.4536.1000 differs from the current version 14.0.4762.1000 which is supported by this program.

 

Steve Chen has described in his blog on why the migration from beta to RTM is not supported. He mentioned that the lesson Sharepoint team learned from 2007 that there may be inconsistency data left from  pre-releases versions. These inconsistent data (from pre-release versions) may generate problems for later releases. However, customers having “Go-Live” license can get help from Microsoft to move data from beta to RTM. The “Go-Live” license is an agreement between customers and Microsoft to help customers to migrate from beta to RTM.

The final learning is “Play with beta releases but don’t dear to develop production code until final version is released”.

Related information can be found in the following links:

http://blogs.technet.com/steve_chen/archive/2010/01/20/sharepoint-2010-public-beta-to-rtm-upgrade.aspx

http://social.msdn.microsoft.com/Forums/en/sharepoint2010general/thread/b55bea00-c907-4468-9cb3-dac208f7ac4e

Friday, October 16, 2009

ClickOnce manifest signing

Introducing Certification

When you get a Software Publisher Certificate (SPC) from a third party CA (say verisign)that is authorized by Microsoft to issue certificate, you actually get two files: a pvk and spc or cer file.

.pvk file which contains the private key information.

.spc or .cer file contains public key information.

In my discussion later I’ll consider having pvk and spc file for signing clickonce application.

To use this certificate you need to generate a Personal Information Exchange file (pfx). You can generate a pfx file from pvk and spc. For details information on how to generate pfx file follow here.

 

Visual Studio Support for Clickonce Manifest signing

Now I’ll consider that you have pfx file and you are ready to sign the clickonce manifest. To sign the clickonce manifest open the properties window of the project and then select signing tab. Then select the “Sign the ClickOnce maifests” check box and you’ll be prompted for selecting the pfx file. Open the pfx file and you’ll be prompted for password. After putting your password set the timestamp server url to http://timestamp.verisign.com/scripts/timstamp.dll. The following figure shows the process in a whole.

image

Figure: Sign clickonce manifests.

 

Separate Signing from Developement

You are done! But this is not not I”m writing this post. The problem is in this process that if you have automated build management system (say using NAnt) then during build you’ll be prompted for password and you don’t want this. You actually want to separate the signing from development. You only need to bother about signing when you deploy on production server. if put directly select pfx file from Visual Studio then every developers will be prompted for the password during build (at least once, then VS will cache it). So you need some way to sign the Clickonce manifest, say in post build event. But Publish doesn’t have any event. So you can’t write post build event in Visual Studio project. So one way is to write batch script and run the script after production deployment build.

ClickOnce Manifest Internals

But before diving deep into the signing procedure let’s discuss about how actually ClickOnce manifest works. If you publish your clickonce app in E:\Clickonce folder then the root folder will contains a file named YOURAPPNAME.applicaiton. Then there will be a folder “Application Files\YOURAPPNAME_VERSION” and there’ll be sever files.

image

Figure: ClickOnce deployment folder structure.

Clickone has two types of manifests: application manifest and deployment manifest. Deployment manifest has one of the three extensions:

1) .applicaiton for executable applicaiton

2) .vsto for office applicaiton

3) .xbap for browser hosted wpf applicaiton

Application manifest has only one extension and that is .manifest.

 

Now if you want to manually sign clickonce manifest then you need to sign both application and deployment manifests. Clickonce manifests contains hashes of all/related files. The following figure shows how application and deployment manifest share hash value.

image

Figure: Application and Deployment manifest hash value calculation.

Sign application and deployment manifests

So if you sign clickonce manifest then you need to sign the application manifest first as deployment manifest depends on application manifest file. So lets’ start with then signing process:

1. Signthe application manifest:

If your application manifest has a .manifest extension and you’ll get the application manifest file in “Applicaiton Files\Application_VERSION” folder. The following command sign a manifest file with pfx.

mage -update MyApplicaiton.exe.manifest -certfile pfxfile.pfx -Password pfxfilepassword

The mage command will be available if you have .net SDK installed.

2. Sign the deployment manifest:

mage -update MyAppName.application -appmanifest MYAppName.exe.manifest -certfile pfxfile.pfx -Password pfxFilePassword

So you are done. But there few points to remember. If your application’s dlls are renamed with deploy then you need to remove this option either the sign will not work. You can remove the .deploy option from visual studio property window > Publish Tab > Options.

image

Figure: Remove .deploy extension from Visual Studio.

Now you can write a batch file which you can run after build and the batch file will sign the clickonce manifests and your manifest signing is totally different from your development.

Wednesday, February 25, 2009

AppOffline.htm mystery

if you create a file named AppOffline.htm in the root directory of the web site user will be redirected to the page. This is useful when we upload something in PROD. We can create a file named AppOffline.htm specifying “site is upgrading………. Please wait for few mins….”, copy it in the root directory of web site and then we can modify PROD files.

So when we need to update the live site content for few moments then we can put the file in the root directory and the site will be offline. Any user trying to access any url of the site will get the appoffline.htm file.. Then when update will be done then the file can be deleted to bring the site online.