About Me

Having 12 years experience in Microsoft technologies.Since more than 7 years working in SharePoint technologies. Expert in providing consultation for SharePoint projects. Hands on with development and administration.

Tuesday 4 October 2011

Steps to create SharePoint components like features, user controls, webparts & most essential components.

Parent directory is by assuming MOSS 2007 has installed in ‘C’ drive:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\
Parent directory is by assuming SPS2010 has installed in ‘C’ drive:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\14\

Features:
Ø  The FEATURES directory is located inside another MOSS 2007 system directory named TEMPLATE
Ø  C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES
Ø  Create a sub folder in FEATURES folder with the feature name.
Ø  Create feature.xml file in the new feature folder which has been created in above step.
Ø  Generate new GUID by using ngen.exe and use in the “Feature Id”.
Ø  Scope attribute takes following parameters
Ø  Web: which means it can be activated and deactivated within the context of the site.
Ø  Site: Your feature will then be activated and deactivated within the scope of a site collection.
Ø  WebApplication: Entire WebApplication
Ø  Farm: Entire web server farm.
Ø  Create elements.xml in the same folder.
Ø  How to install:
§  Either use STSADM GUI tool or use manual process
§  stsadm -o installfeature -filename SubmissionColumns\feature.xml –force
Ø  How to activate:
§  Either use STSADM GUI tool or use manual process
§  stsadm -o activatefeature -filename SubmissionColumns\feature.xml -url http://localhost
Ø  Note: stsadm.exe is available in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN
Event Handlers:
Types of Event Handlers:
Ø  Synchronous(ing): Synch Event Handler occurs before the event is completed
Ø  Asynchronous(ed): Asynch occurs after the event is completed.
Ø  Before events:
Ø  These are the events that SharePoint lists, list items, and sites fire before certain actions take place, which is the reason for its name.
Ø  After events:
Ø  These are the events that SharePoint lists, list items, and sites fire after certain actions take place, hence the name After events.
Ø  Different kinds of event receivers:
§  List events:  For lists and Libraries. Class: SPListEventReceiver
§  Item events:  For Items in lists & libraries. Class: SPItemEventReceiver
§  Web events:  For web applications. Class: SPWebEventReceiver
Ø  How to create?
§  Create Class Library project in Visual Studio 2005 or 2008.
§  Inherit your class with SPListEventReceiver or SPItemEventReceiver or SPWebEventReceiver
§  Assign a strong name key.
§  Compile the project and copy the assembly into GAC
Ø  How to attach?
Three ways to attach:
§  Create console application and add assemblies, classes
§  Use any of event handlers GUI tool to attach (easiest way)
§  Attach in the form of features.  

Deploying Event Handlers using Features:
1.     Create a folder with the feature name in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES
2.     Create feature.xml file in the above created folder.
3.     Add the element <ElementManifest Location="XXXXX.xml" />  in feature.xml
4.     Create XXXX.xml file in the same folder.
5.     The xxx.xml file is like as follows
6.     <Elements> <Receivers ListTemplateId="107"> <Receiver> <Name>Task Deleting Handler</Name> <Type>ItemDeleting</Type> <SequenceNumber>10000</SequenceNumber> <Assembly>WSSListHandlers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=552e0b5f5440b3f2</Assembly> <Class>WSSListHandlers.TaskListHandler</Class> <Data></Data> <Filter></Filter>
</Receiver> </Receivers> </Elements>

Point to be noted here:  Create <Receivers ListTemplateId="107"> tag and mention the ListTemplateId, which you are going to attach your event handler. The ID varies between each template.  107 is for Tasks list.

Here's a little codesnippet to get those ListTemplateIds, just add a Reference to Microsoft.Sharepoint.dll.
string[] typeNames = System.Enum.GetNames(typeof(SPListTemplateType));
Array typeValues = System.Enum.GetValues(typeof(SPListTemplateType));

int j = 0;

foreach (int i in typeValues)
{
Console.WriteLine(typeNames[j++].ToString() + " " + i.ToString ());
}
    • 100 – Generic List
    • 101 – Document Library
    • 102 – Survey
    • 103 – Links List
    • 104 – Announcements List
    • 105 – Contacts List
    • 106 – Events List
    • 107 – Tasks List
    • 108 – Discussion Board
    • 109 – Picture Library
    • 110 – Data Sources
    • 111 – Site Template Gallery
    • 112 – User Information List
    • 113 – Web Part Gallery
    • 114 – List Template Gallery
    • 115 – XML Form Library
    • 116 – Master Pages Gallery
    • 117 – No-Code Workflows
    • 118 – Custom Workflow Process
    • 119 – Wiki Page Library
    • 120 – Custom grid for a list
    • 130 – Data Connection Library
    • 140 – Workflow History
    • 150 – Gantt Tasks List
    • 200 – Meeting Workspace Series List
    • 201 – Meeting Workspace Agenda List
    • 202 – Meeting Workspace Attendees List
    • 204 – Meeting Workspace Decisions List
    • 207 – Meeting Workspace Objectives List
    • 210 – Meeting Workspace text box
    • 211 – Meeting Workspace Things To Bring List
    • 212 – Meeting Workspace Pages List
    • 301 – Blog Posts List
    • 302 – Blog Comments List
    • 303 – Blog Categories List
    • 1100 – Issue Tracking
    • 1200 – Administrator Tasks List

Attach an event handler to a specific SharePoint list
When we attach an event handler through Features in SharePoint using “ListTypeId”, it attaches event handlers to all the lists of that particular type. This will result in a large performance hit. To execute the written code for a particular list we will have to check either with ListId or ContentTypeId.
So, here is a way of attaching an event handler to a specific list on
“FeatureActivated” and to remove the event handler from the list on “FeatureDeactivating”. This is the best method I can find as of now for attaching and removing the event handler to a specific SharePoint List.

const string assembly = "ListItemPermissions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5";
const string listReceiverName = "ListItemPermissions.ListItemPermissionsItemEventReceiver";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
// get a reference to the current SPWeb
SPWeb _SPWeb = SPContext.Current.Web;
_SPWeb.AllowUnsafeUpdates = true;
// get a reference to the "Projects" list
SPList _projectsList = (SPList)_SPWeb.Lists["Projects"];

// if the "projectsList" list exists
if (_projectsList != null)
{
// create an empty Guid
Guid _ItemUpdatedGuid = Guid.Empty;
Guid _ItemAddedGuid = Guid.Empty;

// enumerate thru all of the event receiver definitions, attempting to
// locate the one we are adding
foreach (SPEventReceiverDefinition _SPEventReceiverDefinition in _projectsList.EventReceivers)
{
// if we find the event receiver we are about to add
// record its Guid
if (_SPEventReceiverDefinition.Type == SPEventReceiverType.ItemUpdated &&
_SPEventReceiverDefinition.Assembly == assembly &&
_SPEventReceiverDefinition.Class == listReceiverName)
{
_ItemUpdatedGuid = _SPEventReceiverDefinition.Id;
}

if (_SPEventReceiverDefinition.Type == SPEventReceiverType.ItemAdded &&
_SPEventReceiverDefinition.Assembly == assembly &&
_SPEventReceiverDefinition.Class == listReceiverName)
{
_ItemAddedGuid = _SPEventReceiverDefinition.Id;
}
}

// if we did not find the event receiver we are adding, add it
if (_ItemUpdatedGuid == Guid.Empty)
{
_projectsList.EventReceivers.Add(SPEventReceiverType.ItemUpdated, assembly, listReceiverName);
}
if (_ItemAddedGuid == Guid.Empty)
{
_projectsList.EventReceivers.Add(SPEventReceiverType.ItemAdded, assembly, listReceiverName);
}

_projectsList.Update();
_SPWeb.Update();
_SPWeb.AllowUnsafeUpdates = false;
}
}

catch (System.Exception ex)
{
PortalLog.LogString(ex.StackTrace);
throw new SPException(ex.Message);
}
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
try
{
SPWeb _SPWeb = SPContext.Current.Web;
_SPWeb.AllowUnsafeUpdates = true;
// get a reference to the "Projects" list
SPList _projectsList = (SPList)_SPWeb.Lists["Projects"];
while(_projectsList.EventReceivers.Count > 0)
{
if (_projectsList.EventReceivers[_projectsList.EventReceivers.Count-1].Assembly.Equals(assembly))
{
_projectsList.EventReceivers[_projectsList.EventReceivers.Count-1].Delete();
}
} // looping thru event receivers.

_projectsList.Update();
_SPWeb.Update();
_SPWeb.AllowUnsafeUpdates = false;
}
catch (System.Exception ex)
{
PortalLog.LogString(ex.StackTrace);
throw new SPException(ex.Message);
}
}



Deployment of Feature Receivers
Two ways to deploy:
  1. Make solution package
  2. Create a feature
Make solution package (brief steps)
manifest file, and add some entries into it. (If you are lost here, goto my other blog post about deploying features.)
<Solution SolutionId="{NEW GUID HERE}" xmlns=http://schemas.microsoft.com/sharepoint/>
<Assemblies>
<Assembly DeploymentTarget="GlobalAssemblyCache" Location="LookFeelFeatureReceiver.dll">
</Assembly>
</Assemblies>
</Solution>
Finally, we need to add a cab file to hold the DLL and manifest.xml files so that we can deploy these to SharePoint.
(Also see the other blog post on this part if you are lost) 
After a clean build, rename the cab to a wsp file, and copy to a SharePoint server. 
Finally we are going to need to run some STSADM commands. 
Stsadm.exe –o addsolution –filename LookFeelFeatureReceiver.wsp
Stsadm.exe –o deploysolution –name LookFeelFeatureReceiver.wsp –immediate –allowGacDeployment
The -allowGacDeployment is important here.
Create a feature way
Feature.xml should be
<?xml version=”1.0” encoding=”utf-8”?>
<Feature Id="b3c387b3-5f74-4054-bb70-8b45c7549afa"
Title="MyThemeFeature"
Scope="Web"
Version="1.0.0.0"
Hidden="FALSE"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/"
ReceiverAssembly=" MyThemeFeature, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
ReceiverClass=" MyThemeFeature. FeatureReceiver1" >   (mention your assembly info)
<ElementManifests />
</Feature>
Webparts
There are 2 ways to create webparts in SharePoint 2007.
1.     Manual process
2.     Using VseWss extensions
Manual Process:
1.     Create a class library project in VS 2005 or VS 2008.
2.     Add assembly system.web
3.     Include System.Web.UI.WebControls.WebParts
4.     Inherit your class with WebPart class
5.     Over ride your controls in CreateChildControls() method.
6.     Assign a strong name key and compile.
7.     Copy assembly in GAC
8.     Add your webpart entry as a safe in SharePoint web application web.config file.
9.     Create a .webpart XML file and upload into the SharePoint site webpart gallery list.
10.  Reset IIS.
11.  Add your webpart in webpart zone.
Automation process with the help of VseWSS:
1.     Install VseWss 1.1 or later versions, which create predefined templates in VS 2005 or 2008.
2.     Create a project by selecting Visual C-# à SharePoint-àWebPart
3.     Right click on Solution and select properties.
4.     Under Debug add your SharePoint Url in the “Start browser with URL” option.
5.     Got to Build and Click Build the project.
6.     Go to Build and Click Deploy the project.
           
Deploy Web Part as a feature
This time we're talking about how to deploy web parts as a feature. Now, deploying custom web parts the manual way is a bit of a pain - the following things are required for the web part to be used:-
·         the assembly containing the compiled web part class to be in the GAC (or site bin with appropriate CAS policy)
·         a SafeControls entry in the site web.config to tell SharePoint this control is administrator-approved
·         the .webpart (or .dwp) file which contains the web part definition (configuration) to be uploaded to the site's web part gallery
Assuming the user has appropriate permissions, the web part can then be added to a WebPartZone on a web part page. The first thing to say is that there are 2 ways of automating this process:-
·         use VSeWSS to create a feature to deploy the web part - simply hit F5 to deploy to your local server; this also generates a SharePoint solution package (.wsp) which can be deployed to other environments.
·         create a feature 'manually' by creating the files (e.g. feature.xml, elements file etc.) by hand
Once the webpart has been developed, we need to create the manifest file, specifying the feature details, assembly, SafeControls entry, and webpart definition file (.webpart):-
Then, we need the feature.xml file which points to the elements file and tells the framework there is another file to process (that being the .webpart file):-

The elements.xml file should look something like:-
Here ‘113’ means web parts gallery
Finally, a .webpart file should be generated to define the metadata and default property values of the webpart.




User Controls
Ø  Create a web user control in ASP.NET.
Ø  Compile the User control.
Ø  Copy the dll into GAC
Ø  Add your dll as safe control in SharePoint web application web.config file.
Ø  Copy the .ascx file into C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS folder
Ø  Follow above process to create a webpart.
Ø  Define your user control in WebPart Render() method.
Ø  Ccontrol _myControl;                                                                   String err;     
Ø  _myControl.RenderControl(writer);
Ø 
Ø  Refer the user control path in CreateChildControls() method.
myControl = this.Page.LoadControl("\\_layouts\\WebUserControl.ascx");
this.Controls.Add (_myControl);

Custom Field Types (Custom Columns)
Ø  Open Visual Studio
Ø  Create a user control (ASCX), with a “SharePoint:RenderingTemplate”
Ø  Create a class file (CS) for the business logic - in my case, to check if the current user role was in a particular group (from a web.config setting)
Ø  Create another class file (CS) for the SharePoint custom field definition
Ø  Create the necessary XML files – and install to GAC + 12-hive
To create a custom field type, you can create a project in Visual Studio that contains the following items:
Ø  An  ASP.NET user control that defines an editing surface known as a Rendering Template, an .ascx file to store the rendering template and controls you want to make up the field
Ø  A public class to initialize and manage the Rendering Template (field control) which should be inherited by BaseFieldControl class.
Ø  A public class that defines the actual custom field type and should be inherited by any of SPFieldText, SPFieldNumber, SPFieldDateTime, or SPFieldMultiColumn according to situation.
Ø  An XML file that is used to deploy the custom field type and format should be fldtypes_XXXX.xml
Ø  All fldtypes_xxxx.xml files should be in TEMPLATE/XML
Ø  The fldtypes_XXXX.xml should have the .dll information.
Ø  The user control file named XXXXX.ascx contains a Rendering Template control tag that acts as the editing surface for a custom field type.
Ø  All .ascx files have been deployed inside the WSS RootFiles directory within the directory structure of TEMPLATE/CONTROLTEMPLATES.
Ø  This is the directory where WSS requires you to deploy any .ascx file that defines a RenderTemplate control that is to be used by a custom field type.
Ø  The actual .ascx file should have the Rendering Template Id
Example:
Ø  <SharePoint:RenderingTemplate ID="HelloWorldRendingTemplate" runat="server"> <Template> <asp:TextBox ID="txtUserInput" runat="server" CssClass="ms-long" /> </Template> </SharePoint:RenderingTemplate>
Ø  Rendering template id and user control file name should be same.

Custom List Definition
Creating a custom submission list definition
1. Create a folder named SubmissionsList in the FEATURES directory.
2. Create a xml file named feature.xml that contains the following information:
<?xml version="1.0" encoding="utf-8" ?>
<Feature 
    Id="{6d2c42db-782c-417e-9c7c-2c941ef52b92}"
    Title="Submission List"
    Description="This feature contains a submission list definition"
    Version="12.0.0.0"
    Scope="Site"
     xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
        <ElementManifest Location="ListTemplate\Submissions.xml" />
    </ElementManifests>
</Feature>
3. Create a folder named ListTemplate inside the SubmissionsList folder and add an xml file named Submissions.xml that contains the following information:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <ListTemplate
          Name="Submissions"
          Type="6500"
          BaseType="0"
          OnQuickLaunch="TRUE"
          SecurityBits="11"
          Sequence="360"
          DisplayName="Submissions"
          Description="Create a submissions list when you want to allow users to submit submissions on a document"
          Image="/_layouts/images/itgen.gif" />
</Elements>
Here we are defining a unique type number for our list (which can be used if we want to include this list in a custom site definition), the sequence it should appear in the ‘create’ page and other basic attributes. Note the displayname used must match the folder that contains the list schema defined in the next step.
4. Create a folder named Submissions inside the SubmissionsList folder and copy the FEATURES\CustomList\CustList\Schema.xml file into the Submissions folder.
5. Update the ContentTypes element in the Schema.xml file to the following:
<ContentTypes>
    <ContentTypeRef ID="0x01AB">
        <Folder TargetName="Submission" />
    </ContentTypeRef>
    <ContentTypeRef ID="0x0120" />
</ContentTypes>
Here we define our custom ‘submission’ content type as the base type for this list. The columns defined in this content type are then shown on the ‘add new item’ page.
6. Update the Fields element in the Schema.xml file to the following:
<Fields>
    <Field
        Name="Title"
        ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
        DisplayName="Title"
        Sealed="TRUE"
        SourceID="http://schemas.microsoft.com/sharepoint/v3"
        StaticName="Title">                      
    </Field>
    <Field
        ID="{475c2610-c157-4b91-9e2d-6855031b3538}"
        Name="FullName"
        DisplayName="$Resources:core,Full_Name;"
        Type="Text"
        SourceID="http://schemas.microsoft.com/sharepoint/v3"
        StaticName="FullName">                   
    </Field>
    <Field
        ID="{fce16b4c-fe53-4793-aaab-b4892e736d15}"
        Name="Email"
        DisplayName="$Resources:core,E-mail_Address;"
        Type="Text"
        SourceID="http://schemas.microsoft.com/sharepoint/v3"
        StaticName="Email">                      
    </Field>
    <Field ID="{374e02cc-fe2e-4247-8762-e69242f9ff94}"
        Name="SubmissionComments"
        SourceID="http://schemas.microsoft.com/sharepoint/v3"
        StaticName="SubmissionComments"
        Group="Submission Columns"
        Type="Note"
        DisplayName="Comments"
        Sortable="FALSE"
        Description="Comments on the submission"
        Sealed="TRUE"
        UnlimitedLengthInDocumentLibrary="TRUE"
        AllowDeletion="TRUE"
        ShowInFileDlg="FALSE">
    </Field>
</Fields>
Here we define the custom fields from our content type that we want to use in our list.
7. Lastly update the ViewFields element to contain the columns we want to display on our default list view:
<ViewFields>
    <FieldRef Name="Attachments">
    </FieldRef>
    <FieldRef Name="LinkTitle">
    </FieldRef>
    <FieldRef Name="FullName">
    </FieldRef>
    <FieldRef Name="Email">
    </FieldRef>
    <FieldRef Name="SubmissionComments">
    </FieldRef>
</ViewFields>
8. Activate the feature using the following commands:
stsadm -o installfeature -filename SubmissionList\feature.xml -force
stsadm -o activatefeature -filename SubmissionList\feature.xml -url http://localhost

iisreset

Ø  Create a folder in Local_Drive:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATES\FEATURES and give it an appropriate name, such as SimpleListFeature.
Ø  Create feature.xml file with unique GUID and mention the elements.xml file location.
Ø  <?xml version="1.0" encoding="utf-8" ?>
<Feature 
    Id="{6d2c42db-782c-417e-9c7c-2c941ef52b92}"
    Title="Submission List"
    Description="This feature contains a submission list definition"
    Version="12.0.0.0"
    Scope="Site"
     xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
        <ElementManifest Location="ListTemplate\Submissions.xml" />
    </ElementManifests>
</Feature>

Ø  In the new folder create an Elements.xml file that identifies the list template and specifies information to display on the Create Page. Give it a Type value that is above 10000 and different from any other custom list definitions used in your deployment:
Ø  Create a subfolder that has the same name as that assigned to the list template in the previous step.
Ø  Create a Schema.xml file in the new subfolder to define the list. You can copy and modify the Schema.xml file of an existing list Feature to define special fields for a custom list definition. (you can copy the existing custom list schema.xml from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\CustomList\CustList)
Ø  At a command prompt, type the following commands to install the Feature in the deployment, and then activate the Feature on a specified subsite.
Ø  stsadm -o installfeature -filename SimpleListFeature\Feature.xml
Ø  stsadm -o activatefeature -name SimpleListFeature -url http://Server/Site/Subsite
Note: You can define your own columns & content types in the custom list definition.
             You can add these custom columns in schema.xml file well.
Source: http://ari.provoke.co.nz/archive/2007/04/18/creating-a-custom-sharepoint-2007-list-definition.aspx
http://msdn.microsoft.com/en-us/library/ms466023.aspx

Custom Site Columns
Ø  Create a folder named XXXX in the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES (FEATURES) directory.
Ø  Create an xml file named feature.xml inside this folder that contains the following information:
Ø  Create a xml file named xxxxxx.xml that contains the following information:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <Field ID="{374e02cc-fe2e-4247-8762-e69242f9ff94}"
        Name="SubmissionComments"
        SourceID="http://schemas.microsoft.com/sharepoint/v3"
        StaticName="SubmissionComments"
        Group="Submission Columns"
        Type="Note"
        DisplayName="Comments"
        Sortable="FALSE"
        Description="Comments on the submission"
        Sealed="TRUE"
        UnlimitedLengthInDocumentLibrary="TRUE"
        AllowDeletion="TRUE"
        ShowInFileDlg="FALSE">
    </Field>
</Elements>
Ø  Here we are defining the system name (Name and StaticName) the base type (Type) and several other attributes of our site column. The FEATURES\fields folder contains examples of default site columns, and is useful in understanding how all these attributes are used.
Ø  Activate the feature using the following commands (in a command window, from the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN directory):
stsadm -o installfeature -filename SubmissionColumns\feature.xml -force
stsadm -o activatefeature -filename SubmissionColumns\feature.xml -url http://localhost

Custom Content Type
Ø  Create a folder named SubmissionCT in the FEATURES directory.
Ø  Create a xml file named feature.xml that contains the following information:
Ø  Create a xml file named submissionct.xml that contains the following information:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <ContentType
        ID="0x01AB"
        Name="Submission"
        Group="Submission Content Types"
        Description="Create a new submission"
        Version="0">
        <FieldRefs>
            <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Title" Sealed="TRUE"/>
            <FieldRef ID="{475c2610-c157-4b91-9e2d-6855031b3538}" Name="FullName" Required="TRUE" />
            <FieldRef ID="{fce16b4c-fe53-4793-aaab-b4892e736d15}" Name="Email" Required="TRUE" />
            <FieldRef ID="{374e02cc-fe2e-4247-8762-e69242f9ff94}" Name="SubmissionComment" Required="TRUE" />
        </FieldRefs>
    </ContentType>
</Elements>
Ø  Here we are defining basic attributes for our content type and the site columns that we will be using. One important piece of information is the ID attribute. This tells us that our content type is based on the content type with ID 0x01, the ‘Item’ content type. The FEATURES\ctypes folder can be used to find the ID’s of system content types we might want to use as a base. You should also check that the ID of your new content type is unique.
Ø  Another important point to note is that the FieldRef ID's must match ID's for existing site columns. We can see that the ID of the SubmissionComment field matches that of the site column we defined in step 1 by looking at the elements xml file we used to define the column. To find out the ID of other fields we want to use you can look in the FEATURES\fields folder to see a list of all the default field/column types.
Ø  Activate the feature using the following commands:
stsadm -o installfeature -filename SubmissionCT\feature.xml -force
stsadm -o activatefeature -filename SubmissionCT\feature.xml -url http://localhost


Content Types Development along with Site columns
There are two ways where we can develop content types in SharePoint 2007.
  1. Through declarative XML tags
  2. Through SharePoint API model.

Through Declarative XML approach:
·         Defining Site Columns
  1. Because the development of site columns is typically the first step in the development of site content types, you can begin by examining techniques for creating site columns.
  2. To create site columns with declarative XML, simply include a Field element for each site column. The Field element enables you to specify the name, data type, and other settings for the site column. The ID attribute is the unique identifier for the field and is a GUID
<Field
  ID="{D713DCD2-6626-47a1-A23F-3C24CD66A3F9}"
  Name="Amount"
  DisplayName="Amount"
  Type="Currency"
  Decimals="2"
  Min="0"
  Group="Financial Columns">
</Field>
·         Defining Content Types
1.       To create content types with declarative XML, include a ContentType element for each content type. The ContentType element must have an ID attribute that specifies its parent, but that is also globally unique. The best practice for creating content type IDs is to begin with the ID of the parent content type, append two zeroes, and then append a GUID with all of the punctuation removed. This approach ensures that your content type has a unique ID. Additional custom content types that inherit from your content type can simply append "01", "02", and so on. Table 3 shows the inheritance chain for the financial content types, including the IDs.
2.       The ContentType elements must also include FieldRef elements that reference the ID of the site columns to include in the content type. This structure is required because content types do not actually contain site columns. Instead, content types reference the site column definitions.
<ContentType
  ID="0x01010012841A8869DB425cB829C3875EC558CE"
  Name="Financial Document"
  Description="Base financial document"
  Version="0"
  Group="Financial Document Types" >
  <FieldRefs>
   <FieldRef
    ID="{D713DCD2-6626-47a1-A23F-3C24CD66A3F9}"
    Name="Amount" DisplayName="Amount" />
  </FieldRefs>
</ContentType>
·         Finalizing the Definitions
1.       After the content types are created and referencing the site columns, you perform additional configuration of the content type. Often, you will want your content types to have a document template for use whenever a new instance of the content type is created.
2.       When you use declarative XML to specify a document template, the template must be loaded into the site by using a Module element. The Module element specifies where to load the document template for the content type.
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
 <Module Name="PurchaseOrderDocumentTemplate"
         Url="_cts/Purchase Order" RootWebOnly="TRUE">
  <File Url="PurchaseOrder.docx" Type="Ghostable" />  
 </Module>
 <Module Name="InvoiceDocumentTemplate"
         Url="_cts/Invoice" RootWebOnly="TRUE">
  <File Url="Invoice.docx" Type="Ghostable" />
 </Module>
 <Field
  ID="{D713DCD2-6626-47a1-A23F-3C24CD66A3F9}" Name="Amount"
  DisplayName="Amount" Type="Currency" Decimals="2"
  Min="0" Group="Financial Columns">
 </Field>
 <Field
  ID="{8AE47811-8E98-4f49-AAE8-CF52A4BF83AB}" Name="DepartmentName"
  DisplayName="Department" Type="Choice" Group="Financial Columns">
  <CHOICES>
   <CHOICE>Administration</CHOICE>
   <CHOICE>Information Services</CHOICE>
   <CHOICE>Facilities</CHOICE>
   <CHOICE>Operations</CHOICE>
   <CHOICE>Sales</CHOICE>
   <CHOICE>Marketing</CHOICE>
  </CHOICES>
 </Field>
 <Field
  ID="{E9FC44C2-9036-490d-9D7C-599A9366779F}" Name="ClientName"
  DisplayName="Client Name" Type="Text" Group="Financial Columns">
 </Field>
 <ContentType
  ID="0x01010012841A8869DB425cB829C3875EC558CE"
  Name="Financial Document"
  Description="Base financial document"
  Version="0" Group="Financial Document Types" >
  <FieldRefs>
   <FieldRef
    ID="{D713DCD2-6626-47a1-A23F-3C24CD66A3F9}"
    Name="Amount" DisplayName="Amount" />
  </FieldRefs>
 </ContentType>
 <ContentType
  ID="0x01010012841A8869DB425cB829C3875EC558CE01"
  Name="Purchase Order" Version="0"
  Group="Financial Document Types">
  <DocumentTemplate TargetName="PurchaseOrder.docx" />
  <FieldRefs>
   <FieldRef
    ID="{8AE47811-8E98-4f49-AAE8-CF52A4BF83AB}"
    Name="DepartmentName" DisplayName="Department" />
  </FieldRefs>
 </ContentType>
 <ContentType
  ID="0x01010012841A8869DB425cB829C3875EC558CE02"
  Name="Invoice"
  Version="0"
  Group="Financial Document Types">
  <DocumentTemplate TargetName="Invoice.docx" />
  <FieldRefs>
   <FieldRef
    ID="{E9FC44C2-9036-490d-9D7C-599A9366779F}"
    Name="ClientName" DisplayName="Client Name" />
  </FieldRefs>
 </ContentType>
</Elements>
·         Deploying Content Types
·         You should always deploy content types as Features to support a smooth migration from development to production and to make content types available within sites through Feature activation. If you want the content types to be available throughout the entire portal, deploy them by using a site collection Feature, which installs the content types in the top-level Site Content Type Gallery. This gallery is available to every subsite in the collection.
·         Deploying content types that are created by using declarative XML is a simple matter of referencing the element manifest file in the Feature.xml file. With the element manifest, you should also include references to the document templates.
<?xml version="1.0" encoding="utf-8" ?>
<Feature
  Title="Financial Content Types (XML)"
  Description="XML-based Content types for financial documents"
  Scope="Site"
  Id="AE790003-91BB-499c-A2C9-CF491EDA8B03"
  Hidden="FALSE"
  xmlns="http://schemas.microsoft.com/sharepoint/"
  Version="1.0.0.0"
  >
  <ElementManifests>
    <ElementManifest Location="CTypes.xml" />
    <ElementFile Location="PurchaseOrder.docx"/>
    <ElementFile Location="Invoice.docx"/>
  </ElementManifests>
</Feature>
If you wish to accomplish this programmatically...
1.     Create a ItemUpdating event handler and attach it to your target list. I would create a feature and feature receiver to do the attaching.
  1. In the ItemUpdating event handler, there are two values you want to look at: properties.ListItem["Approval"] this will give you the original value properties.AfterProperties["Approval"] this is the updated value
  2. First you need to take the SPWorkflowManager Object.
  3. SPWorkflowManager objWorkflowManager = null;


  4. Then use SPWorkflowAssociationCollection object. every List and Document library has association with the workflow, to get this we have to use this object to collect all workflows which are associated with the List or DocumentLibrary.

    SPWorkflowAssociationCollection objWorkflowAssociationCollection = null;

    I consider that i am using Event Handler, if you are using this code anywhere else, change the Web and Site objects accordingly.
    We have WorkflowManager object at Site Level, so first we will take it.
  5. objWorkflowManager = item.Web.Site.WorkflowManager;
Then we will take all association of the workflow for specific list.
  1. objWorkflowAssociationCollection = item.ParentList.WorkflowAssociations;

Now consider a scenario, where you have multiple workflows associated with the same list or document library. So First we need to find the correct Workflow Association to trigger only that workflow.

So for that first Loop through all Associations,

  1. foreach (SPWorkflowAssociation objWorkflowAssociation in objWorkflowAssociationCollection)

    {
    if (String.Compare(objWorkflowAssociation.BaseId.ToString("B"), {"Workflow_GUID"}, true) == 0)

    {

    //We found our workflow association that we want to trigger.

    //Replace the workflow_GUID with the GUID of the workflow feature that you
    //have deployed.

    objWorkflowManager.StartWorkflow(item, objWorkflowAssociation, objWorkflowAssociation.AssociationData, true);
    //The above line will start the workflow...
    break;
    }
    }
How to find GUID of workflow?
You could iterate in code through all the associated workflows of a document library and use the debugger to find out the GUID of the workflow you want.
9.     Or an easier way is to right click on an item in your doc library and select "Workflows" from the dropdown menu.
10.   
11.  You'll then see a list of all the workflows associated to your document library.  Go ahead and click on one of them.
12. 
You can use a feature to modify most of the menus in SharePoint – you do this by using Custom Actions, which is the recommended method in MOSS. With SharePoint 2003 you had to modify/override the ows.js file, but MS made it much easier with SharePoint 2007. And trust me when I say it’s easier
To add an item to the document context menu, add this to your elements file in your feature:
<CustomAction
      Title=”My Context Menu Item”
      RegistrationType=”List”
      RegistrationId=”101″
      Location=”EditControlBlock”
      Sequence=”1000″
      ImageUrl=”/_layouts/Images/myicon.gif”>
<UrlAction Url=”~site/_layouts/1033/mypage.aspx?listId={ListId}&amp;itemId={ItemId}”/>
</CustomAction>
You’ll see there are some replacement tags like ~site, {ListId}, and {ItemId}. You can use these tags to pass site and list info info through to your page.


Deploy Theme as a Feature

Packaging SharePoint Themes

SharePoint themes are an interesting feature in SharePoint that allow site owners to quickly change the appearance of colors, icons, and images buy injecting an additional style sheet that overrides some of the existing styles found in the core.css style sheet. Creating a custom theme involves a couple of simple steps:
  1. Creating a new folder in the 12/TEMPLATE/THEMES directory
  2. Creating a theme.css file to override the out of the box styles defined in the core.css style sheet in the directory created in the previous step
  3. Creating a mossExtension.css file which is appended to theme.css file to create a the actual style sheet that is actually used when viewing pages in the SharePoint site
  4. Creating a <directory name>.inf file that contains some basic setup information about the theme
  5. Adding all the images and icons referenced in the custom style sheets in step 2 and 3 to the new directory created in step 1
  6. Modifying the SPTHEMES.XML file in the 12/TEMPLATE/LAYOUTS/1033 directory
A word of caution! Modifying the SPTHEMES.XML is not a recommended customization practice since this file maybe overwritten by future SharePoint service packs.
It’s easy enough to take an existing theme directory out of the 12/TEMPLATE/THEMES directory, make a copy of it, rename the directory, rename the INF file, edit the INF, theme.css, and mossExtension.css file to create a new theme. However, this approach is not practical in a production SharePoint farm. The practical approach is to use the WSS solution framework to create our own solution package to deploy the custom theme. For more information, I covered the creation of solution packages (WSP files) in detail in a previous post. Let’s take a quick look at the solution manifest for our theme package:
<?xml version=1.0encoding=utf-8 ?>
<
Solution xmlns=http://schemas.microsoft.com/sharepoint/
         
DeploymentServerType=ApplicationServer
         
ResetWebServer=TRUE
         
SolutionId=D250636F-0A26-4019-8425-A5232D592C10>
 <
TemplateFiles>
  <
TemplateFile Location=LAYOUTS/1033/SPTHEMES.XML/>
  <
TemplateFile Location=LAYOUTS/1033/OOB_SPTHEMES.XML/>
  <
TemplateFile Location=THEMES/MYNEWTHEME/MYNEWTHEME.INF/>
  <
TemplateFile Location=THEMES/MYNEWTHEME/mossExtension.css/>
  <
TemplateFile Location=THEMES/MYNEWTHEME/theme.css/>
  <!–
Additional images and icons (gif, jpg, png files)
       can be added here using <TemplateFile> elements
–>
 </
TemplateFiles>
</
Solution>
The solution includes a modified SPTHEMES.XML file where we added an element to define the custom theme named MYNEWTHEME. You can also see that we included a copy of the original SPTHEMES.XML file and renamed it OOB_SPTHEMES.XML since it’s always a good idea to have back up copy of the file we modified. Finally, you see the critical MYNEWTHEME.INF, mossExtension.css, and theme.css files. For the sake of brevity, additional image and icon files were excluded on purpose.
The WSP file was then generated using a directive file and the MAKECAB utility (directive files and the MAKECAB utility are also covered in my previous post) and deployed using the STSADM utility.

Packaging Branding

There are many different SharePoint Products and Technologies branding techniques. In the presentation, I demonstrated how quickly and easily we can use a solution to deploy custom style sheets, master pages, and page layouts and how we can use a feature receiver to programmatically apply the branding using the object model. Again for the sake of brevity, the demonstration illustrated how a master page can be deployed and applied. However, a similar approach can be used for page layouts, cascading style sheets, XSL files, image files, and any other branding components and artifacts.
The solution manifest to accomplish our task is relatively basic. Here it is:
<?xml version=1.0encoding=utf-8 ?>
<
Solution xmlns=http://schemas.microsoft.com/sharepoint/
         
DeploymentServerType=WebFrontEnd
         
SolutionId=A250636F-0A26-4019-8425-A5232D592C10>
 <
FeatureManifests>
  <
FeatureManifest Location=MyBranding\feature.xml/>
 </
FeatureManifests>
 <
Assemblies>
  <
Assembly DeploymentTarget=GlobalAssemblyCache
           
Location=CustomThemeFeature.dll />
  </
Assemblies>
</
Solution>
As you can see, the solution manifest only includes a feature manifest and an assembly that will be deployed to the GAC. The assembly only contains a custom feature receiver class that programatically applies the custom master page and the custom theme discussed earlier in this post.
Let’s take a look at the feature manifest:
<Feature xmlns=http://schemas.microsoft.com/sharepoint/
        
Id=D250636F-0A26-4019-8425-A5232D592C11
        
Description=My custom master page feature.
        
Title=My Custom Branding
        
ReceiverAssembly=CustomThemeFeature, Version=1.0.0.0, PublicKeyToken=1ff5d2fddf39f61b, Culture=neutral
        
ReceiverClass=CustomThemeFeature.FeatureReceiver
        
Scope=Web>
 <
ElementManifests>
  <
ElementManifest Location=elements.xml/>
  <
ElementFile Location=mycustom.master/>
 </
ElementManifests>
</
Feature>
The feature manifest is also pretty simple as it includes one element manifest and one element file. The element file is the custom master page that was created. The element manifest will declare a module that will be used to populate the master page gallery with the custom master page. An important thing to notice here is the ReceiverAssembly and ReceiverClass attributes in the Feature element. These attributes tell the WSS solution framework to use a custom assembly and feature receiver class to handle the feature related events. We will look at the feature receiver class in a bit. First lets take a look the element manifest:
<Elements xmlns=http://schemas.microsoft.com/sharepoint/>
 <
Module Name=MasterPages
         List=116
        
Url=_catalogs/masterpage>
  <
File Url=mycustom.master
        Type=GhostableInLibrary />
 </
Module>
</
Elements>
The element manifest is simploy responsible for populating the master page gallery with the custom master page. If our solution and feature also had custom page layouts, those can be added to the master page gallery by adding File child elements to the Module element. Additionally, we could add more modules to populate the style library with custom style sheets and/or XSL files or add other media files to other SharePoint libraries.
Finally let’s take a look at the custom feature receiver class:
using Microsoft.SharePoint;
namespace CustomThemeFeature { public class FeatureReceiver: SPFeatureReceiver {
 
public override void FeatureActivated(SPFeatureReceiverProperties properties) {
   SPWeb site = (SPWeb)properties.Feature.Parent;
   site.MasterUrl =
“/_catalogs/masterpage/mycustom.master”;
   site.CustomMasterUrl =
“/_catalogs/masterpage/mycustom.master”;
   site.ApplyTheme(
“MYNEWTHEME”);
   site.Update();
  }
 
public override void FeatureDeactivating(SPFeatureReceiverProperties properties) {
SPWeb web = properties.Feature.Parent as SPWeb;
web.ApplyTheme("none");
}
  
public override void FeatureInstalled(SPFeatureReceiverProperties properties) {}
  
public override void FeatureUninstalling(SPFeatureReceiverProperties properties) {}
 }
}
The class simply takes advantage of the feature activated event and to set the values of the master pages and apply a theme to the SPWeb object where the feature is activated.
Similar to the custom theme discussed earlier in this post, a WSP solution file was created using a directive file and the MAKECAB utility. The solution was then deployed with the STSADM utility. The feature was installed with the STSADM utility as well.





Deploy Master Page and Page layout as a feature
Source: http://spreflections.wordpress.com/2008/09/24/deploy-master-page-and-page-layout-as-a-feature/
The following is the detailed the instructions of how to deploy Master Page and Custom Page Layout together

1.       The following is the directory structure which I suggest when creating your own features
 
       2.       Under the PageLayouts folder you will see two files:
·         MoscowLayout.aspx: this page is the custom page layout you created
·         MoscowLayout.xml: this is the manifest files that identifies your custom page layout

               You can put as much as custom page layout pages as you want in this folder, but you only need
               one manifest file

3.       The content of MoscowLayout.xml should be looks like:

                <Module Name =”MOSCOWPageLayouts” Url =”_catalogs/masterpage”
                                 Path =”PageLayouts” RootWebOnly =”TRUE”>
                                <File Url =”MoscowLayout.aspx” Type =”GhostableInLibrary”>
                                                <Property Name =”Title” Value=”XXX”/>
                                                <Property Name =”MasterPageDescription” Value=”XXX”/>
                                                <Property Name =”ContentType” Value =”$Resources:cmscore,contenttype_pagelayout_name;”/>
                                                <Property Name=”PublishingPreviewImage” Value =”~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/ArticleLeft.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/ArticleLeft.png”/>
                                </File>
                </Module>
</Elements>


 Module:   indicate to SharePoint the location of the aspx pages. MoscowLayout.aspx is part of your feature and must be copied along with all of the other parts to the features folder. During the activation of your feature, it will be dropped in the Master Page and Page Layout gallery.

File:  defines the path to your page and the type. GhostableInLibrary tells SharePoint to create a list item to go with your file when it is added to MasterPage and Page Layout gallery.  Ghostable  is used if you are provisioning a file outside a document library

Two important properties:
ContentType:  OOTB Master Page Gallery has two content type associated with it. The value will either be master page or page layout.

Publishing AssociationConetentType: Specify ContentType to which your custom page layout is associated. The value of this one is composed of the name of your content type and the ID of content type. If this value is omitted, by default your layout will be associated with the basic ‘Page’ content type from the publishing feature

4.       You put your master page, css file into MoscowMasterPage. The wollongongmaster.xml manifest file should look like the following:

<Elements xmlns=”http://schemas.microsoft.com/sharepoint/”>
                <Module Name=”MasterPages” List=”116″ Url=”_catalogs/masterpage”>
                                <File Url=”Moscow.master” Type=”GhostableInLibrary” />
                </Module>
                <Module Name=”WollongongStyles” Url=”Style Library” RootWebOnly =”TRUE”>
                                <File Url=”Moscow.css” Type =”GhostableInLibrary”/>
                </Module>
</Elements>

5.       Under the folder MoscowFeature, you will see Feature.xml, it will look similar to
<Feature Id=”{6EAA33DF-AD39-4a2c-B5AB-972A576D7CF4}”
                                 Title=”Moscow Branding”
                Description=”Master Page and page layouts for Moscow”
                Version=”1.0.0.0″
                Scope=”Site”
                Hidden=”FALSE” xmlns=”http://schemas.microsoft.com/sharepoint/“>
                <ElementManifests>
                                <ElementFile Location=”PageLayouts\MoscowLayout.aspx”/>
                                <ElementManifest Location=”PageLayouts\MoscowLayout.xml” />
                                <ElementManifest Location =”MoscowMasterPage\wollongongmaster.xml”/>
                </ElementManifests>
</Feature>

It contains ElementManifest files for master page and page layout.

This is just an example to give you a general idea of how custom page layout should be deployed. It depends on how individual elements are structured. And install.bat file is important as well because you need to copy the files to the right location in your 12 hives.

About Solution Package (.wsp)
A Solution is a package of SharePoint items for deployment - in physical terms it is a cabinet file (.cab) which is given the extension of .wsp to differentiate it from standard .cab files. Other articles on this blog cover the idea of using SharePoint Features to deploy functionality, so let's also be clear on the relationship between Features and Solutions. In general terms, some of the tasks which cannot be done with a Feature alone but can be done with a Solution include:
·         Deployment of certain files to the filesystem, e.g. an assembly for workflow or web parts, custom files which will reside in the ‘12’ folder 
·         Deployment of web part definition files (.webpart)
·         Web.config modifications e.g. the ‘SafeControls’ entry required for a custom web part
·         Code Access Security config modifications e.g. those required for custom web parts not running from the GAC
In addition to being able to do these things, Solutions can also contain Features. The way I think of it is that the Solution wraps the Feature.
How Solutions are specified
The key file used to specify what a Solution package consists of is the manifest.xml file. Going back to my earlier post on deploying web parts, the manifest.xml file for that scenario looks like this:
<Solution xmlns="http://schemas.microsoft.com/sharepoint/" SolutionId="122C0F04-78B7-4d42-9378-6F8B4F93ADD1">
  <FeatureManifests>
    <!-- note this is the location in the cab file! -->
    <FeatureManifest Location="COB.Demo.WebPartDeployment.WriteToFileWebPart\feature.xml" />
  </FeatureManifests>
  <Assemblies>
    <Assembly     Location="COB.Demo.WebPartDeployment.WriteToFileWebPart\COB.Demo.WebPartDeployment.WriteToFileWebPart.dll"
        DeploymentTarget="GlobalAssemblyCache">
      <SafeControls>
        <SafeControl Assembly="COB.Demo.WebPartDeployment.WriteToFileWebPart, COB.Demo.WebPartDeployment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
                    Namespace="COB.Demo.WebPartDeployment"
                    Safe="True"
                    TypeName="*" />
        </SafeControls>
    </Assembly>
  </Assemblies>
  <DwpFiles>
    <DwpFile
     Location="COB.Demo.WebPartDeployment.WriteToFileWebPart\COB.Demo.WebPartDeployment.WriteToFileWebPart.webpart"
      FileName="COB.Demo.WebPartDeployment.WriteToFileWebPart.webpart" />
  </DwpFiles>
</Solution>
This is assuming the web part is being deployed to the GAC - for this illustration this is a simpler scenario than deploying to the web application's bin directory, where Code Access Security (CAS) policy would also be required. Effectively, the manifest specifies that the Solution package consists of the following:
·         a Feature with a header file named 'feature.xml'
·         an assembly for deployment to the GAC named 'COB.Demo.WebPartDeployment.WriteToFileWebPart.dll'
·         an entry in the SafeControls section of the application's web.config file, specifying all types in the specified assembly should be treated as safe
·         a web part definition file named 'COB.Demo.WebPartDeployment.WriteToFileWebPart.webpart' - this will be deployed to the web part gallery on the site
Importantly, all these details in the manifest.xml file are only used by SharePoint when the generated Solution package is deployed. They are effectively the instructions which say "go and get this item from the .wsp file and put it here". The actual process for generating the .wsp file is another task.
Building Solution packages
There are 2 options for building the actual package - build it manually using makecab.exe, or use an automated solution - there are several community-developed tools/techniques available. Since it's always good practise to understand what's actually happening in such processes, we'll cover how to do it manually here.
The first step is to write a .ddf (Diamond Directive File). This is a set of instructions for makecab.exe on how to build the folder hierarchy inside the .cab file. For my web part example, my file looks like:
.OPTION Explicit
.Set CabinetNameTemplate="COB.Demo.WebPartDeployment.WriteToFileWebPart.wsp" 
.Set DiskDirectory1="Package"
;***

manifest.xml

;** this directory name is used for the folder name under 12\TEMPLATE\Features, so should
;** match up with what you want to call the feature!
.Set DestinationDir=COB.Demo.WebPartDeployment.WriteToFileWebPart
elements.xml
feature.xml

.Set DestinationDir=COB.Demo.WebPartDeployment.WriteToFileWebPart
WebPart\COB.Demo.WebPartDeployment.WriteToFileWebPart.webpart
WebPart\COB.Demo.WebPartDeployment.WriteToFileWebPart.dll

;***
This file tells makecab.exe to do the following:
·         create a .cab file named 'COB.Demo.WebPartDeployment.WriteToFileWebPart.wsp'
·         put the 'manfest.xml' file at the root of the hierarchy
·         put the 'elements.xml' and 'feature.xml' files in a subfolder called 'COB.Demo.WebPartDeployment.WriteToFileWebPart'
·         also put the 2 other files (with extensions .webpart and .dll) in this same subfolder, but that makecab.exe should look for these files in a subfolder on the main filesystem called 'WebPart'
This instructions file is then passed to makecab.exe with the following command-line command:
D:\SolutionDeployment\Development\COB.Demo.WebPartDeployment>"C:\Program Files\Microsoft Cabinet SDK\BIN\MAKECAB.EXE" /f COB.Demo.WebPartDeployment.ddf
Couple of things to note here. At the command prompt we have ensured the current directory is the directory where all our Solution files are kept. This ensures that our relative references in the .ddf file above can be resolved. We pass the /f parameter to indicate we are passing a directives file, and also pass the location of this file.
Assuming all the files/references are OK, this results in a .cab file with a .wsp extension which will be created in a subfolder under the current directory called 'Package' (the folder will be created for you if it doesn't exist). We now have a Solution package which can be deployed to another SharePoint server. But first let's take a peek inside - this can be done by temporarily renaming the extension to .cab. You should then see something like:
Deploying the Solution to other SharePoint servers
The final part is to actually deploy the Solution. First the .wsp file must be copied to the target server, and then we will use STSADM (SharePoint's command-line admin tool) to actually deploy the Solution. The following are the commands which used to perform the deployment:
stsadm -o addsolution -filename COB.Demo.WebPartDeployment.WriteToFileWebPart.wsp
stsadm -o deploysolution -name COB.Demo.WebPartDeployment.WriteToFileWebPart.wsp
   -url http://myWebApplication -immediate -allowGacDeployment -allowCasPolicies -force

The first command simply adds the Solution package to SharePoint's Solution store in the config database, and the second one actually performs the deployment of the package to the specified web application.
Rather than write these commands at the command-line each time you wish to deploy the package, chances are over time you'll package these commands up into STSADM scripts which do the work. As an example, the script I use for the webparts example looks like:
:begin
@echo off

set solutionName=COB.Demo.WebPartDeployment.WriteToFileWebPart
set url=http://myWebApplication
set featureName=COB.Demo.WebPartDeployment.WriteToFileWebPart
@set PATH=C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN;%PATH%

echo --- Attempting to deactivate/retract existing solution...

stsadm -o deactivatefeature -name %featureName% -url %url% -force
stsadm -o retractsolution -name %solutionName%.wsp -url %url% -immediate
stsadm -o execadmsvcjobs
stsadm -o deletesolution -name %solutionName%.wsp -override
rem stsadm -o execadmsvcjobs

echo --- Adding solution %solutionName% to solution store...

stsadm -o addsolution -filename %solutionName%.wsp

if errorlevel == 0 goto :deploySolution

echo ### Error adding solution %solutionName%
echo .
goto end

:deploySolution
echo --- Deploying solution %solutionName%...

stsadm -o deploysolution -name %solutionName%.wsp -url %url% -immediate -allowGacDeployment -allowCasPolicies -force
stsadm -o execadmsvcjobs

if errorlevel == 0 goto :activateFeature

echo ### Error deploying solution %solutionName%
echo .
goto end

:activateFeature

echo --- Activating features in solution %solutionName%...

stsadm -o activatefeature -name %featureName% -url %url% -force

if errorlevel == 0 goto :success

echo ### Error activating feature %featureName%
echo .
goto end

:success
echo Successfully deployed solution and activated feature(s)..
echo .
goto end

:end
pause

Following the script through, this basically does the work of safely upgrading the Solution (in case it has been deployed previously), and also activating the Feature within the Solution.

No comments:

Post a Comment