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)
Tuesday, 20 May 2008
Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007
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\
• Drive:\Documents and Settings\\
• 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! [;)]