Pages

Search This Blog

Tuesday, November 8, 2011

Add Custom Property Panel in Custom WebPart like OOB SharePoint Property Panel via Reflection


Sometime we have a requirement to create custom property in WebPart. But the custom Property will add in “Miscellaneous” section or added in blank section if we add property via custom tool part. Now if you want to create panel like OOB Panel “Layout, Appearance etc.” then use below method.
Below class is static class for enabling extension method on ToolPart class. You need to add below class in your solution and add namespace in your toolpart class where you want to use this method
namespace ExtensionMethods
{
    public static class CustomExtensions
    {
        public static Panel GetPropertyPanel(this ToolPart currentToolPart, Table table, StringsTitle)
        {
            Panel controlPanel = new Panel();
            controlPanel.ID = "propertyPanelHideDisplay";
            controlPanel.Attributes.Add("id", currentToolPart.ClientID + "_" + controlPanel.ID);
            controlPanel.Controls.Add(table);

            Literal lt = new Literal();
            String sScript = "<script language='javascript'>\n" +
                            " var objDiv = document.getElementById('" + currentToolPart.ClientID + "_" + controlPanel.ID + "');\n" +
                            " objDiv.parentNode.parentNode.parentNode.attributes.removeNamedItem('colspan');\n" +
                            " objDiv.parentNode.parentNode.parentNode.attributes.removeNamedItem('class'); \n" +
                            "</script>";
            lt.Text = sScript;
            controlPanel.Controls.Add(lt);

            Type type = typeof(SPSite);
            Assembly assembly = type.Assembly;

            var bindingFlags = BindingFlags.Instance | BindingFlags.Public |BindingFlags.NonPublic;

            Panel propertyPanel = (Panel)assembly.CreateInstance("Microsoft.SharePoint.WebPartPages.TPPanel", false, bindingFlags,null,
               new object[] { sTitle, controlPanel, true }, null, null);

            return propertyPanel;
        }
  
 }
}

Below is the sample class for ToolPart for adding Panel by using above class

using ExtensionMethods;
namespace CustomNamespace
{
    class CustomToolpart : ToolPart
    {
        private DropDownList ddlDisplayType;
     
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            CreateControls();
        }

        public override void ApplyChanges()
        {
            EnsureChildControls();
            SendDataToWebPart();
        }

        private void SendDataToWebPart()
        {
            EnsureChildControls();
            CustomWebPart customWebPart = (CustomWebPart)this.ParentToolPane.SelectedWebPart;

            // Send the custom text to the Web Part.
            if (ddlDisplayType != null)
            {
                customWebPart.Property = ddlDisplayType.SelectedValue;
            }

           
        }

        public override void SyncChanges()
        {
            base.SyncChanges();
           
        }

        private void SetValues()
        {
            ListItem item = null;
            CustomWebPart customWebPart = (CustomWebPart)this.ParentToolPane.SelectedWebPart;
            if (!string.IsNullOrEmpty(customWebPart.Property))
            {
                item = ddlDisplayType.Items.FindByValue(customWebPart.Property);
                if (item != null)
                {
                    ddlDisplayType.SelectedValue = item.Value;
                }
            }
        
           
        }

        public override void CancelChanges()
        {
            base.CancelChanges();
        }


        protected override void RenderToolPart(System.Web.UI.HtmlTextWriter output)
        {
            base.RenderToolPart(output);
        }


        public void CreateControls()
        {
          
            ddlDisplayType = new DropDownList();

            ddlDisplayType.Items.Add("Property 1");
            ddlDisplayType.Items.Add("Property 2");
            ddlDisplayType.Items.Add("Property 3");

            AddControls();
            SetValues();
          
        }

        private void AddControls()
        {
            Table table = new Table();
            TableRow tr = new TableRow();
            TableCell td = new TableCell();
            Literal ltStatic = new Literal();

            ltStatic.Text = "Custom Property";
            td.Controls.Add(ltStatic);
            tr.Cells.Add(td);
            table.Rows.Add(tr);
           
            tr = new TableRow();
            td = new TableCell();
            td.Controls.Add(ddlDisplayType);
            tr.Cells.Add(td);
            table.Rows.Add(tr);

            String sTitle = "Panel Title";
            this.Controls.Add(this.GetPropertyPanel(table, sTitle));
        }
    }
}


In above class bold line will return Panel and add the Panel in ToolPart Pane. Below is the screen shot for the above implementation


Hope it help !!!!

Monday, November 7, 2011

Self Service Site Creation

Bringing-up the out of box feature “Self Service Site Creation“, as the name suggests it does not create a site but actually it gives the freedom to create a site collection by any user (can also specify the permissions) other than the site administrator. It can be used for the end users to create their own site collection under the same URL domain.
In this post I will tell how to use the “Self Service Site Creation“ by customizing the permissions and creating the site using UI as well as the programmatically.
1. Login to the “SharePoint 2010 Central Administration”.
2. Click on the “Manage Web Application” under the “Application Management”.
3. Select the Web Application.
4. Click on the “Self Service Site Creation” icon present in the ribbon.



5. Check the “On” button present on the dialogue box.
6. If require to permit the functionality only to the limited users, then click on the user policy and edit the settings and give the permission to the desired user.
7. Now logon to the http:///_layouts/scsignup.aspx and enter the details to create a new site collection.
8. Or you can also do it programmatically using the “objSite.SelfServiceCreateSite()” method

Sunday, November 6, 2011

Powershell Script for Installing PDF ifilter for Sharepoint 2010

I have created a powershell script for Installing PDF filter in Sharepoint 2010 environment. I have tested it in Windows 2008 R2. Installing a PDF filter is a multi step process since it requires adding the icons in sharepoint _Layouts hive, adding registry entries for the filter, adding PDF extension to Search Service Application and updating DOCICON.XML file.

I have splitted the whole deployment process into 8 steps right from downloading the necessary files from the Adobe site to unzipping and installing the resources.





Below are the commands written in powershell for deploying PDF I filter for Sharepoint 2010. Copy the code and paste it in notepad and save with extension as .ps1. Now right click the file and click 'Run with powershell' to execute the code.

# Constants
$tempfolder = "C:\temp"   # path for temporary location
$pdfFilterDownloadUrl = "http://download.adobe.com/pub/adobe/acrobat/win/9.x/PDFiFilter64installer.zip"
$pdfIconDownloadUrl = "http://www.adobe.com/images/pdficon_small.gif"
$pdfIconDestinationPath = "\c$\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IMAGES\pdf.gif"
$docIconXMLFilePath = "\c$\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\XML\DOCICON.XML"
$pdfDllSystemPath = "\c$\Program Files\Adobe\Adobe PDF iFilter 9 for 64-bit platforms\bin\"
$pdfDllPath = "C:\Program Files\Adobe\Adobe PDF iFilter 9 for 64-bit platforms\bin\PDFFilter.dll"

# Create a Temporary folder if not already exists for downloading the installer and gif image
function createTempFolder()
{
 Get-Item $tempfolder -ErrorVariable err -ErrorAction "SilentlyContinue" | Out-Null
 if ([String]::IsNullOrEmpty($err) -eq $false)
 {
  new-item -type directory -path $tempfolder -ErrorVariable err -ErrorAction "SilentlyContinue" | Out-Null
  $err = ""
 }
}
# method to restart the local iis
function RestartIIS()
{
 Write-Host "Restarting IIS..." -foregroundcolor Yellow
 iisreset /noforce
}
# Method to download the installer
# parameters: $url - url from where to download the file; $destination - physical folder location
function DownloadFile
{
    param([string]$URL, [string]$destination)
 $percentage = 0
    Write-Output ""
    Write-Host "Downloading $URL ..." -foregroundcolor Yellow
    $clnt = new-object System.Net.WebClient -ErrorVariable err -ErrorAction "SilentlyContinue"
    $clnt.DownloadFileAsync($url,$destination)
 do
 {
  $percentage ++
  Write-Progress -Activity 'File Download' -Status "downloading..." -PercentComplete $percentage
  sleep 5
 }
 while($clnt.IsBusy)
    if ([String]::IsNullOrEmpty($err) -eq $true)
 {
  Write-Host "File downloaded sucessfully." -foregroundcolor Green
 }
    else
 {
  Write-Error "Error in download - Either wrong URL or Address not correct. Details: $err"
 }
 $err = ""
}
#If download file has extension as .zip, you need to extract the zip
#parameters: $ZIPname - zip file path; $destination - path for unzipping the file
function extractZipFile
{
 param([string]$ZIPname, [string]$destination)
 $ZIPfile = Get-Item $ZIPname  -ErrorVariable err -ErrorAction "SilentlyContinue"
    if ([String]::IsNullOrEmpty($err) -eq $false)
 {
     Write-Error "ERROR: $err Cannot find $ZIPname"
        exit
    }
    $ZIPfolder = Get-Item $destination  -ErrorVariable err -ErrorAction "SilentlyContinue"
    if ([String]::IsNullOrEmpty($err) -eq $false)
 {
      Write-Error "ERROR: $err Cannot find $ZIPfolder"
         exit
    }
    else
 {
  $zipname = $zipfile.fullname # makes sure the path is absolute
  $zipDestination = $ZIPfolder.fullname # makes sure the destination path is absolute
  $shellApplication = new-object -com shell.application
  $zipPackage = $shellApplication.NameSpace($zipname)
  $destinationFolder = $shellApplication.NameSpace($ZIPdestination)
  $destinationFolder.CopyHere($zipPackage.Items())
  }
}
function AddEnvironmentVariablePath([array] $PathsToAdd)
{
  $VerifiedPathsToAdd = ""
  foreach ($Path in $PathsToAdd) {
    if ($Env:Path -like "*$Path*")
 {
      echo " $Path already in the path"
    }
    else
 {
      $VerifiedPathsToAdd += ";$Path";
    }
  }
  if ($VerifiedPathsToAdd -ne "")
  {
    echo "Adding $VerifiedPathsToAdd to system path"
    [System.Environment]::SetEnvironmentVariable("PATH", $Env:Path + "$VerifiedPathsToAdd","Machine")
  }
}
function InstallPDF_IFilter
{
#load powershell snapin
 Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction "SilentlyContinue" | Out-Null
# Step 1: Create a temp folder for downloading the required files.
 Write-Host "Creating a temporary folder at $tempfolder" -foregroundcolor Yellow
 createTempFolder
 Write-Host "Temporary folder created sucessfully" -foregroundcolor Green
 $farm = get-spfarm
# Step 2: Download the pdf icon from site
 Write-Host "Downloading the PDF icon from $pdfIconDownloadUrl" -foregroundcolor Yellow
 DownloadFile $pdfIconDownloadUrl "$tempfolder/pdf.gif"
 Write-Host "PDF Icon downloaded sucessfully" -foregroundcolor Green
# Step 3: Copy the downloaded Icon on all the servers
 # connecting to all application servers in the farm for copying the icon
    foreach($Server in $farm.servers)
 { 
       if ((($Server.Role -eq "Application") -or ($Server.Role -eq "SingleServer")) -and ($Server.Status -eq "Online"))
  {   
            Write-Output ""
            Write-Host ("Copying the PDF icon to the sharepoint folder on " + $Server.Name + "...") -foregroundcolor Yellow
            $DestFile = "\\" + $Server.name + $pdfIconDestinationPath 
            copy-item "$tempfolder\pdf.gif" -destination $DestFile -ErrorVariable err -ErrorAction "SilentlyContinue"
            if ([String]::IsNullOrEmpty($err) -eq $true)
   {
    Write-Host "PDF Icon Copied." -foregroundcolor Green
   }
            else
   {
    Write-Error "Error occured. Details: $err"
   }
        }
    }
    Write-Output ""

# Step 4: Add .pdf extension to the list of search extensions in the Search Service Appliation
 $err = ""
    Write-Host "Adding .PDF extension to the list of search extensions in the Search Service Appliation..." -foregroundcolor Yellow
    $searchApp = Get-SPEnterpriseSearchServiceApplication
    if ([String]::IsNullOrEmpty($err) -ne $true)
 {
  Write-Error "Error: Search Service Application is missing. Details: $err"
 }

 # Check if the extension already exists or not
    $PDFcheck = get-SPEnterpriseSearchCrawlExtension "pdf" -SearchApplication $searchApp -ErrorVariable err -ErrorAction "SilentlyContinue"
 if([String]::IsNullOrEmpty($PDFcheck) -eq $true)
 {
 $err = ""
 new-SPEnterpriseSearchCrawlExtension "pdf" -SearchApplication $searchApp -ErrorVariable err -ErrorAction "SilentlyContinue" | Out-Null
  if([String]::IsNullOrEmpty($err) -eq $true)
  {
   Write-Host "Extension added sucessfully" -foregroundcolor Green
  }
  else
  {
   Write-Error "Error Occured while adding .pdf extension: $err"
  }
 }
 else
 {
  Write-Host " The .PDF extension is already listed" -foregroundcolor Yellow
 }
 Write-Output ""
   
   
# Step 5: Add pdf extension in the Sharepoint Docicon.XML file

 foreach($Server in $farm.servers)
 { 
 if ((($Server.Role -eq "Application") -or ($Server.Role -eq "SingleServer")) -and ($Server.Status -eq "Online"))
  {
   Write-Output ""
   Write-Host ("Adding pdfs as extension to docicons xml file on " + $Server.name) -foregroundcolor Yellow
   $XMLfile = "\\" + $Server.name + $docIconXMLFilePath
   [xml]$dociconxml = get-content  $XMLfile -ErrorVariable err -ErrorAction "SilentlyContinue"
   if ([String]::IsNullOrEmpty($err) -eq $true)
   {
    $PNGelement = $dociconxml.DocIcons.ByExtension.Mapping | Where-Object { $_.Key -eq "png" }
    $PDFnode = $dociconxml.DocIcons.ByExtension.Mapping | Where-Object { $_.Key -eq "pdf" }
    if ($PDFnode.key -eq "pdf"){
     Write-Host "pdf extension on Docicon.xml file already exists" -foregroundcolor Yellow
    }
    else
    {
    # add a new pdf node to the xml document
    $element = $dociconxml.DocIcons.ByExtension.Mapping[0].clone() # Duplicates an existing node
    $element.key = "pdf"
    $element.value = "pdf.gif"
    $element.OpenControl = ""
    $element.EditText = ""
    $dociconxml.DocIcons.ByExtension.InsertBefore($element,$PNGelement)  | Out-Null # Inserts the new node before the existing PNG element
    $dociconxml.save($XMLfile)
    if ([String]::IsNullOrEmpty($err) -eq $true)
    {
     Write-Host "Entry updated sucessfully" -foregroundcolor Green
    }
    else
    {
     Write-Error "Error occured while adding pdf entry in docicon.xml file. Details: $err" }
    }
   }
   else
   {
    Write-Error "XML not found: $err"
   }                
  }
 }
 Write-Output ""

# Step 6: Download the PDF I Filter from Adobe Site.
 Write-Host "Downloading the PDF Ifilter installer from  $pdfFilterDownloadUrl" -foregroundcolor Yellow
 Write-Host "This may take few minutes depending upon the internet speed..." -foregroundcolor Yellow
 DownloadFile $pdfFilterDownloadUrl "$tempfolder\PDFiFilter64installer.zip"
   
    # Extract the downloaded file which is in .zip format
 Write-Host "Extracting the downloaded Zip" -foregroundcolor Yellow
    extractZipFile "$tempfolder\PDFiFilter64installer.zip" $tempfolder
    Write-Host "File extracted sucessfully" -foregroundcolor Green


    Write-Host "Running the PDF iFilter installer..." -foregroundcolor Yellow
 $proc = Start-Process C:\Windows\System32\msiexec.exe " /passive /i $tempfolder\PDFFilter64installer.msi" -wait -ErrorVariable err -ErrorAction "SilentlyContinue"
 # $LASTEXITCODE - Contains the exit code of the last Win32 executable execution
 if ($LASTEXITCODE -eq "0")
 {
  Write-Host "Installation sucessful" -foregroundcolor Green
 }
 else
 {
  Write-Error "Installed with following error code: $LastExitCode). Details: $err"
 }
 Write-Output ""
   
# Step 7: Add the pdf Dll to system path (Environment variable)
  Write-Host "Adding the pdf dll path to system path..." -foregroundcolor Yellow
  AddEnvironmentVariablePath($pdfDllSystemPath)
  Write-Host "Added Sucessfully" -foregroundcolor Green
 Write-Output ""
   
# Step 8: Add PDF Entries for Sharepoint Search in System Registry
 Write-Host "Adding pdf entries for Sharepoint Search in the registry" -foregroundcolor Yellow
 New-Item -path registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\Filters\.pdf' -ErrorAction "SilentlyContinue" | Out-Null
 New-ItemProperty -Path registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\Filters\.pdf' -Name "Extension" -value ".pdf" -PropertyType string -ErrorAction "SilentlyContinue" | Out-Null
 New-ItemProperty -Path registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\Filters\.pdf' -Name "Mime Types" -value "application/pdf" -PropertyType string -ErrorAction "SilentlyContinue" | Out-Null
 New-ItemProperty -Path registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\Filters\.pdf' -Name "FileTypeBucket" -value "1" -PropertyType dword -ErrorAction "SilentlyContinue" | Out-Null
 New-Item -path registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf' -ErrorAction "SilentlyContinue" | Out-Null
 New-ItemProperty -Path registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf' -name "(Default)" -Value "{E8978DA6-047F-4E3D-9C78-CDBE46041603}" -PropertyType string -ErrorAction "SilentlyContinue" | Out-Null
 Write-Host "Updated Entries sucessfully" -foregroundcolor Green
 Write-Output ""

 # re-register the adobe ifilter dll
 Write-Host "Re-Register the Adobe IFilter dll" -foregroundcolor Yellow
 regsvr32.exe $pdfDllPath
 Write-Host "Registered sucessfully" -foregroundcolor Green

 # Do an IISRESET and restart the Search service
 Write-Host "Restarting IIS.." -foregroundcolor Yellow
 RestartIIS

 Write-Output ""

 Write-Host "Restarting the Search Service..." -foregroundcolor Yellow
 Stop-Service "OSearch14"
 Start-Service "OSearch14"
 Write-Host "Sucess" -foregroundcolor Green
}
#Main method
InstallPDF_IFilter
$exitprompt = Read-Host "PDF Ifilter Installation Complete. Press ENTER to exit"


Download the ps1 file from here.

Wednesday, November 2, 2011

Sharepoint\System "User not found"

Look at the code below and if you try to run this code then it will give error while creating a site because sharepoint doesn't find super admin account



 SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(url))
                {
                    SPSiteCollection workspaces = site.WebApplication.Sites;
                    using (SPSite workspaceSite = workspaces.Add("URL", "Name", "Description", 1033, "BDR#0", SPContext.Current.Web.CurrentUser.LoginName, SPContext.Current.Web.CurrentUser.Name, SPContext.Current.Web.CurrentUser.Email))
                    {
                        return workspaceSite.ID;
                    }
                }
            });




So the workaround of this problem is to get the default site administrator of current site collection and put it in new site collection


 SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(url))
                {
                    SPUser administrator = site.RootWeb.SiteAdministrators[0];
                    SPSiteCollection workspaces = site.WebApplication.Sites;
                    using (SPSite workspaceSite = workspaces.Add("URL", "Name", "Description", 1033, "BDR#0", administrator.LoginName, administrator.Name, administrator.Email))
                    {
                       return workspaceSite.ID;
                    }
                }
            });


BDR#0 is the template Name for document center site. You can use any of the following in site creation process:

IDNameDisplay group
0GLOBAL#0Global template
1STS#0Team Site
1STS#1Blank Site
1STS#2Document Workspace
2MPS#0Basic Meeting Workspace
2MPS#1Blank Meeting Workspace
2MPS#2Decision Meeting Workspace
2MPS#3Social Meeting Workspace
2MPS#4Multipage Meeting Workspace
3CENTRALADMIN#0Central Admin Site
4WIKI#0Wiki Site
7BDR#0Document Center
9BLOG#0Blog
15SGS#0Group Work Site
16TENANTADMIN#0Tenant Admin Site
20SPS#0SharePoint Portal Server Site
21SPSPERS#0SharePoint Portal Server Personal Space
22SPSMSITE#0Personalization Site
30SPSTOC#0Contents area Template
31SPSTOPIC#0Topic area template
32SPSNEWS#0News Site
33SPSNHOME#0News Site
34SPSSITES#0Site Directory
36SPSCOMMU#0Community area template
38SPSREPORTCENTER#0Report Center
39CMSPUBLISHING#0Publishing Site
40OSRV#0Shared Services Administration Site
47SPSPORTAL#0Collaboration Portal
50SRCHCEN#0Enterprise Search Center
51PROFILES#0Profiles
52BLANKINTERNETCONTAINER#0Publishing Portal
53BLANKINTERNET#0Publishing Site
53BLANKINTERNET#1Press Releases Site
53BLANKINTERNET#2Publishing Site with Workflow
54SPSMSITEHOST#0My Site Host
56ENTERWIKI#0Enterprise Wiki
61visprus#0Visio Process Repository
90SRCHCENTERLITE#0Basic Search Center
90SRCHCENTERLITE#1Basic Search Center
2000SRCHCENTERFAST#0FAST Search Center
2764ACCSRV#0Access Services Site
2764ACCSRV#1Assets Web Database
2764ACCSRV#3Charitable Contributions Web Database
2764ACCSRV#4Contacts Web Database
2764ACCSRV#6Issues Web Database
2764ACCSRV#5Projects Web Database
3100PPSMASite#0PerformancePoint
3200BICenterSite#0Business Intelligence Center
14483OFFILE#0(obsolete) Records Center
14483OFFILE#1Records Center

Tuesday, August 23, 2011

The action can't be completed because the file is open in windows explorer

Today i faced a very strange problem where I found that stsadm.exe is locked by windows explorer for no reason. I tried rebooting my server but no luck ... then after struggling for this stupid problem i found a very good software to check and delete the locks on any file on filesystem

"The action can't be completed because the file is open in windows explorer."


http://lockhunter.com/


Explorer Context Menu Integration


LockHunter Main Window


What Files Does Lock Process In Folder?


Unlock, Kill or Remove Phisically Process




Thanks to Lock hunter!!!