Tuesday, 20 May 2008

Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007

Just wanted to make the community aware of a new blog just written by Stefan Gobner (EE Engineer at Microsoft and also a colleague of mine). He explain very well the steps that can be taken by SharePoint Administrators to isolate if a site that contains custom code, which does not properly dispose objects correctly and also how you can isolate components that are leaking these objects.

http://blogs.technet.com/stefan_gossner/archive/2008/05/07/troubleshooting-spsite-spweb-leaks-in-wss-v3-and-moss-2007.aspx

Keep up the great work Stefan your a living legend. :o)

Thursday, 15 May 2008

MOSS AntiVirus Guidelines

I find that a lot of companies implementing MOSS into their organisations are not really thinking about Antivirus software that is running at the Operating System level. There are a number of products out there talking about MOSS Antivirus plug in etc, but these plug in are checking for documents that are being pushed into MOSS for viruses.
MS Fore Front Security for SharePoint:

http://www.microsoft.com/forefront/sharepoint/en/us/product-overview.aspx

McAfee:

http://us.trendmicro.com/us/products/enterprise/portalprotect/index.html

But there seems to be a big area that companies are forgetting about, that can effect the stability of MOSS servers and cause a lot of issues that really confuse IT professionals. The OPERATING SYSTEM ANTIVIRUS. [;)]

To rule out any interference that the operating system antivirus software might bring to SharePoint's stability, the following exclusions from the antivirus real-time scan are recommended:

Windows 2003 Server

· The %systemroot% is normally the C:\WINDOWS or C:\WINNT directory depending on your OS· %systemroot%\System32\Spool (and all the sub-folders and files)· %systemroot%\SoftwareDistribution\Datastore· Any Network Drives that are mapped Refer to the following article for information:
KB822158 - Virus scanning recommendations for computers that are running Windows
Server 2003, Windows 2000, or Windows XP
http://support.microsoft.com/kb/822158

Internet Information Server

• The IIS compression directory (default compression directory is %systemroot%\IIS Temporary Compressed Files)
• %systemroot%\system32\inetsrv folder
• Files that have the .log extension

Refer to the following knowledge base articles for reference:
KB817442 - IIS 6.0: Antivirus Scanning of IIS Compression Directory May Result in 0-Byte File http://support.microsoft.com/kb/817442
KB821749 - Antivirus software may cause IIS to stop unexpectedly http://support.microsoft.com/kb/821749


SQL Server

• Exclude .MDF, .LDF, .NDF, .TRN, .BAK and .SLS
• Exclude sqlmangr.exe and sqlservr.exe
• SQL folder and databases files (or database file types) from scanning for performance reasons:

KB309422 - Guidelines for choosing antivirus software to run on the computers that are running SQL Server http://support.microsoft.com/kb/309422


WSS 3,0 / MOSS 2007

• Drive:\Program Files\Microsoft Office Servers\12.0
• Drive:\Program Files\Common Files\Microsoft Shared\web server extensions\12
• Drive:\DOCUME~1\ALLUSE~1\APPLICATION DATA\MICROSOFT\FIREWALL CLIENT\*
• Drive:\WINDOWS\Temp\WebTempDir\*
• Drive:\DOCUMENTS AND SETTINGS\\LOCAL SETTINGS\APPLICATION DATA\*
• Drive:\Documents and Settings\\\Local Settings\Temp\*
• Drive:\WINDOWS\system32\LogFiles
• W3wp.exe, cbd.exe, cidaemon.exe, owstimer.exe (WSS)
(where Drive: is the drive letter where you installed SharePoint Portal Server)



MOM

· Drive:\Documents and Settings\All Users\Application Data\Microsoft\Microsoft Operations Manager
· Drive:\Program Files\Microsoft Operations Manager 2005


If you are using Trend Micro the follow these guide lines:

• Temp folder: C:\Program Files\Trend Micro\PortalProtect\temp
• Quarantine folder, whose default location is:
Drive:\Program Files\Trend Micro\PortalProtect\Quarantine
• Backup folder, whose default location is:
Drive:\Program Files\Trend Micro\PortalProtect\Backup


The following link will provide you how you can configure MOSS anti-virus, not Operating System Anti-Virus.

http://technet2.microsoft.com/Office/f/?en-us/library/1289e6e2-03e0-4f10-8921-e516187891c61033.mspx


One of my recomendation before logging Microsoft PSS calls is to make sure you have these guidelines applied in your environment, this could save a lot of time & money with regard to support issues. I hope this helps. [:P]

I thought I would add this to the post; the offical KB article associated to "Folders may have to be excluded from antivirus scanning when you use a file-level antivirus program in Windows SharePoint Services 3.0 or in SharePoint Server 2007" has finally arrived: http://support.microsoft.com/kb/952167

Closing of the SPWeb or SPSite Object within Web Part Development

I wrote a base class for one of my clients and started to gather some web part information within my base class inheritted from my Web Part. I started to use the base class and it worked well, until I wanted to edit the web part and tried to change some of the properties attached to the web part. As soon as I applied the changes I would get an error of, "The SPWeb object is no longer valid". Looking through my code I realised I was explicitly closing the spweb object in a final statement. Code looked like this;


SPWeb oSite = SPControl.GetContextWeb(Context);
try
{
return oSite.ID.ToString();
}
catch (Exception exm)
{
throw new Exception(exm.Message);
}
finally
{
oSite.Dispose();
}


I removed the oSite.Disposed from my finally section and it all worked. [:D]

What I realised was that when you are using the Current Context to create a spweb object, you should not close or dispose of the object, or use it within a using statement, [using statement automatically call's the dispose method at the end of the using section] because other places within your site page will more then likely want to use this object. E.G when you want to change a property of a web part, etc...

There is a great article on MSDN that provides developers with best practices of disposing sharepoint services object.

Creating your own custom Base Class with your own MOSS Web Part

[;)] I had a requirement that required me to create a custom base for web parts to provide a common library for web part development within MOSS. I started to research on how this could be done and found very little information that explained the whole process of trying to achieve this and literally any form of reference to this topic in the 3.0 WSS SDK August 2007 did not exist. So I needed to do something to assist the development community.

So lets cut the chase and start showing you how this is done.

Firstly we need to create a new class project within Visual Studio and lets call this WebPartBase. In this example we will retrieve the webpart id and title of the webpart and place this in a protected string called WebPartID and WebPartTitle, I have also included some of the site properties into the base class. Our Base class will inherit from the System.Web.UI.WebControls.WebParts.WebPart base class, which is the base class Microsoft provide you to inherit for developing web parts. Our custom web part will inherit our custom base class, which for the purpose of the blog will only be two properties from the webpart and three properties from the Site object and place them into a strings. As soon as we inherit our base class we automatically inherit these strings into our web part. When we put this into perspective, you have the whole .Net framework their available to you as a developer that could be used as a library for comon tasks that you may require for all your web part development. e.g. Application Logging, Standardise on variable name's across your Line of Business applications for all web parts, custom behaviour across the board for all web parts, etc. I think you get the picture. [;)]

Lets Get Started.

1. Create New Class Project within Visual Studio 2005 and call this WebPartBase.

Add the following bit of code into your WebPartBase class so it should like something like this.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;


using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;


namespace bobby.habib.base
{

public class PortletBase : System.Web.UI.WebControls.WebParts.WebPart
{
///


/// Public default constructor.
///

public PortletBase()
{

}

#region Web Part Settings

protected string WebPartID
{
get
{
return base.ID;
}
}

protected string WebPartTitle
{
get
{
return base.DisplayTitle;
}
}

#endregion

#region Site Settings

protected string SiteID
{
get
{
try
{
SPWeb oSite = SPControl.GetContextWeb(Context);
try
{

return oSite.ID.ToString();
}
catch (Exception exm)
{
throw new Exception(exm.Message);
}
finally
{
oSite.Dispose();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}

}
}

protected string SiteTitle
{
get
{
try
{
SPWeb oSite = SPControl.GetContextWeb(Context);
try
{

return oSite.Title;
}
catch (Exception exm)
{
throw new Exception(exm.Message);
}
finally
{
oSite.Dispose();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}

}
}

protected string SiteName
{
get
{
try
{
SPWeb oSite = SPControl.GetContextWeb(Context);
try
{

return oSite.Name;
}
catch (Exception exm)
{
throw new Exception(exm.Message);
}
finally
{
oSite.Dispose();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}

}
}

#endregion



}
}


2. Complie this code. You will notice that we automatically will inherit a number of values that could be used, as part of your framework library for web part development.

WebPartID
WebPartTitle
SiteID
SiteTitle
SiteName
3. The next step is to now create a web part that will inherit from the custom base class we have just built, rather then using the System.Web.UI.WebControls.WebParts.WebPart base class. So lets create a new web part using visual studio, when creating your web part you must add a reference in your web part project to the custom base class we have just created.

Your web part project should look like this;

using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

using bobby.habib.base;


namespace Bobby.Habib.WebParts.BaseTest

{

public class BobbyHTest : PortletBase
{
public BobbyHTest()
{
this.ExportMode = WebPartExportMode.All;
}

#region GUI Controls

// GUI Panels
private Panel _MainPanel;

#endregion



protected override void Render(HtmlTextWriter writer)
{
_MainPanel.RenderControl(writer);
}

protected override void CreateChildControls()
{

#region Control Declaration

_MainPanel = new Panel();

#endregion

Table outerTable = new Table();
outerTable.CellPadding = 0;
outerTable.CellSpacing = 0;
outerTable.Width = 400;

// Row 1

TableRow row = new TableRow();
TableCell cell = new TableCell();
cell.Width = 800;
string strTxT = string.Empty;
strTxT = strTxT + "Web Part Information
";
strTxT = strTxT + "base.ID - " + WebPartID + "
";
strTxT = strTxT + "base.Title - " + WebPartTitle + "
";
strTxT = strTxT + "Site Information
";
strTxT = strTxT + "Site ID - " + SiteID + "
";
strTxT = strTxT + "Site Name - " + SiteName + "
";
strTxT = strTxT + "Site Title - " + SiteTitle + "
";
strTxT = strTxT + "Display Title - " + WebPartTitle + "
";

cell.Text = strTxT;

row.Cells.Add(cell);
outerTable.Rows.Add(row);
_MainPanel.Controls.Add(outerTable);
base.CreateChildControls();
}
}
}


4. Compile the above code.

5. If you have the Visual Studio 2005 and have installed Visual Studio 2005 extensions for WSS3, you could go into the web part project properties and do the following;

In the Debug Tab in the project properties, click on the radio button that says "Start Browser with URL:" and enter the URL for your MOSS environment.
Assign a Strong Name Key to your base class and you could assign a Strong Name Key to your web part if you wouyld like to place this in the GAC.
In the SharePoint Solution Tab, complete the Solution, Feature and Element information. This behined the scences updates the values you enter in your solution, feature and element xml files that will be used during the deployment mechanism.
Hit F5 only and this will rebuild the project and deploy the solution into MOSS by creating a .wsp file and deploys the .wsp file.
6. You may need to copy your custom base class to the GAC, if you have not configured your solution files to copy the base class into the GAC. If during the time of deployment you find that the project starts error during the deployment. The likely cause is your web part cannot see the custom base class in the GAC and throws a reflection error. Ensure that the base class is in the GAC and is registred as a safe control in the web.config file of the site you are trying to deploy too.

7. Add the web part into a site page in MOSS and you will see the property values being displayed in the web part, that have been inherited from our custom base class.

I hope this helps a developer. [:P]

List Types & List Internal ID available within MOSS 2007

The following lists the default lists types and their internal sharepoint ID available in MOSS 2007. This references list can prove to be handy when creating your own Site Definitions, List Definitions and for Event Handlers:

Value Description

100 Generic List

101 Document Library

102 Survey

103 Links List

104 Announcement List

105 ContactsList

106 Events List

107 Tasks List

108 Discussion Board

109 Picture Library

110 Data Sources

111 Site Template Gallery

113 Web Part Gallery

114 List Template Gallery

115 XML Form Library

120 Custom Grid for a List

200 Meeting Series List

201 Meeting Agenda List

202 Meeting Attendees List

204 Meeting Decisions List

207 Meeting Objectives List

210 Meeting Text Box

211 Meeting things To Bring List

212 Meeting Workspace Pages List

300 Portal Sites List

1100 Issues Tracking

2002 Personal Document Library

2003 Private Document Library

One of the interesting points in the above list is the lack of numbering. You may have noted that 112 is not in the above list for example. But if you go to any Site Setting page within a MOSS site and in the Site Actions option click People & Group which takes you to a page that displays users and groups. Right hand click this page and view HTML source on this page. Schroll down to the bottom of the page and what you will notice is a hidden object in the HTML referencing the ListTemplate ID that displays the value of 112. INTERESTING! [;)]