As we know some time it's bit trick to terminate/cancel a workflow.. Which made me create this web part, so that I can delegate my job to the power user so that they can manager it better! And also gives me some extra time to concentrate on my deadlines.
Challenges:
Very first that you need to have proper admin access to see "Terminate this workflow now" link
When you click on the workflow hyper link on the library item
Here is the web part UI:
Note: ID is the document list item id; you can make more fancy by providing the file name or even loading the active workflow items once selected the document library name
Code for Process Button:
private void CancelWF(string ListName, string ItemId)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite siteColl = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb site = siteColl.OpenWeb())
{
if (site != null)
{
try
{
SPList workflowTasks = site.Lists["Tasks"];
SPList doc = site.Lists[ListName];
SPListItem docItem = doc.GetItemById(Convert.ToInt32(ItemId));
foreach (SPListItem listItem in docItem.ListItems)
{
site.AllowUnsafeUpdates = true;
foreach (SPWorkflow itemWorkflow in listItem.Workflows)
{
SPWorkflowManager.CancelWorkflow(itemWorkflow);
_lblMessage.Text = string.Format(("Administratively Canceled Workflow for the ItemId: {0} / File Name : {1}"), ItemId, listItem.File.Name);
_lblMessage.ForeColor = Color.Blue;
}
site.AllowUnsafeUpdates = false;
}
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
});
}
End results:
Tuesday, November 8, 2011
Thursday, July 28, 2011
Updating Timer Job Schedule
Some time we need to build and deploy a timer job with specific schedule say hourly or daily.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace UpdateTimerJob
{
class Program
{
static void Main(string[] args)
{
updateTimer();
}
static void updateTimer()
{
using (SPSite site = new SPSite("http://sp2010/sites/timer/"))
{ foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{ if (job.Title == "WorkflowEscalation")
{
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
job.Schedule = schedule;
job.Update();
Console.WriteLine("START UPDATING... ");
}
Console.WriteLine("JOB: " + job.Title);
}
}
}
} }
Note: this need to run on the server; you can further modify this app to read site, title & schedule, then update accordingly
But for testing with the business or on your own , you don't want to wait for a day to see the change
Here is a simple console app code which you can use to change timer schedule for testing for any other reason
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace UpdateTimerJob
{
class Program
{
static void Main(string[] args)
{
updateTimer();
}
static void updateTimer()
{
using (SPSite site = new SPSite("http://sp2010/sites/timer/"))
{ foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{ if (job.Title == "WorkflowEscalation")
{
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
job.Schedule = schedule;
job.Update();
Console.WriteLine("START UPDATING... ");
}
Console.WriteLine("JOB: " + job.Title);
}
}
}
} }
Note: this need to run on the server; you can further modify this app to read site, title & schedule, then update accordingly
Wednesday, July 27, 2011
Timer Job With Trick
Timer Job our good old friend, for further details or quick start take a look at this http://technet.microsoft.com/en-us/library/cc678870(office.12).aspx
A little know trick I have implement in my timer job so that it install only on Web front end or Single server (ex. DEV box, usually all in one box).
const string JOB_DEFINITION_NAME = "EscalationTimerJob";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
#region ONLY WebFrontEnd/SingleServer
SPSite site = properties.Feature.Parent as SPSite;
SPWebApplication webApp = site.WebApplication;
//make sure job isn't already registered
if (webApp == null)
{
throw new SPException("Error obtaining reference to Web application.");
}
foreach (SPJobDefinition job in webApp.JobDefinitions)
{ if (job.Name == JOB_DEFINITION_NAME)
job.Delete();
}
foreach (SPServer server in SPFarm.Local.Servers)
{ if (server.Role == SPServerRole.SingleServer || server.Role == SPServerRole.WebFrontEnd)
{
//Install the Job
WorkflowEscalation taskJob = new WorkflowEscalation(JOB_DEFINITION_NAME, webApp, server, SPJobLockType.Job);
SPHourlySchedule schedule = new SPHourlySchedule(); //Every Hour
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
taskJob.Schedule = schedule;
taskJob.Update();
}
}
#endregion
});
}
{
this.Title = jobName;
}
Usual code for installing in on all the servers:
const string JOB_DEFINITION_NAME = "EscalationTimerJob";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
#region For Multiple Servers
SPSite site = properties.Feature.Parent as SPSite;
//make sure job isn't already registered
if (site.WebApplication == null)
{
throw new SPException("Error obtaining reference to Web application.");
}
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == JOB_DEFINITION_NAME)
job.Delete();
}
//Install the Job
WorkflowEscalation taskJob = new WorkflowEscalation(JOB_DEFINITION_NAME, site.WebApplication);
SPHourlySchedule schedule = new SPHourlySchedule(); //Every Hour
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
taskJob.Schedule = schedule;
taskJob.Update();
#endregion
});
}
A little know trick I have implement in my timer job so that it install only on Web front end or Single server (ex. DEV box, usually all in one box).
const string JOB_DEFINITION_NAME = "EscalationTimerJob";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
#region ONLY WebFrontEnd/SingleServer
SPSite site = properties.Feature.Parent as SPSite;
SPWebApplication webApp = site.WebApplication;
//make sure job isn't already registered
if (webApp == null)
{
throw new SPException("Error obtaining reference to Web application.");
}
foreach (SPJobDefinition job in webApp.JobDefinitions)
{ if (job.Name == JOB_DEFINITION_NAME)
job.Delete();
}
foreach (SPServer server in SPFarm.Local.Servers)
{ if (server.Role == SPServerRole.SingleServer || server.Role == SPServerRole.WebFrontEnd)
{
//Install the Job
WorkflowEscalation taskJob = new WorkflowEscalation(JOB_DEFINITION_NAME, webApp, server, SPJobLockType.Job);
SPHourlySchedule schedule = new SPHourlySchedule(); //Every Hour
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
taskJob.Schedule = schedule;
taskJob.Update();
}
}
#endregion
});
}
Note:
1. Added RunWithElevatedPrivileges, so that job definition will be create when activated even without full access. Feature activation runs under the application pool account. So it needs to be a farm administrator which will be mitigate by implementing RunWithElevatedPrivileges
2. Also make sure you also implemented below in your main execute() file
public WorkflowEscalation(string jobName, SPWebApplication webApp, SPServer server, SPJobLockType targetType): base(jobName, webApp, server, targetType){
this.Title = jobName;
}
Usual code for installing in on all the servers:
const string JOB_DEFINITION_NAME = "EscalationTimerJob";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
#region For Multiple Servers
SPSite site = properties.Feature.Parent as SPSite;
//make sure job isn't already registered
if (site.WebApplication == null)
{
throw new SPException("Error obtaining reference to Web application.");
}
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == JOB_DEFINITION_NAME)
job.Delete();
}
//Install the Job
WorkflowEscalation taskJob = new WorkflowEscalation(JOB_DEFINITION_NAME, site.WebApplication);
SPHourlySchedule schedule = new SPHourlySchedule(); //Every Hour
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
taskJob.Schedule = schedule;
taskJob.Update();
#endregion
});
}
Wednesday, March 16, 2011
Customizing the Access Denied Message (AccessDenied.aspx)
Request from client to customize the default access denied error message!!
By Default:
After Customizing the accessdenied.aspx page:
Note: If you want to be more fancy, you can replace the simple.master page with your own master page!
Parts been customizable as show:
Achieved by modifying 2 files
1. SharePoint resource file wss.en-US.resx (from Virtual Directory \App_GlobalResources\wss.en-US.resx)
2. AccessDenied.aspx (from C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS)
Note: Please keep the Original file as a backup
CSS:
<style type="text/css" >
BODY #s4-simple-card H1 {margin-bottom:10px; color:#5b4b3e ; font-size:2em; font-weight:normal;padding-top:3px}
.ms-sectionheader {font-family: Verdana, Arial, sans-serif; color:#595959; font-size:2em }
.ms-descriptiontext {text-align:left; font-family:Verdana, Arial, sans-serif; color:#3f3f3f;font-size:10pt}
A:link, .ms-descriptiontext A:visited, .ms-descriptiontext A:hover { color:#0072BC; font-weight:bold; text-decoration:none; }
.s4-simple-iconcont { z-index:2; background-image: url('/_layouts/images/setcredentials_32x32.png'); HEIGHT: 60px; TOP: 10px;
background-position:left center; background-repeat: no-repeat; }
.s4-simple-iconcont img {display:none;}
</style >
By Default:
Note: If you want to be more fancy, you can replace the simple.master page with your own master page!
Parts been customizable as show:
Achieved by modifying 2 files
1. SharePoint resource file wss.en-US.resx (from Virtual Directory \App_GlobalResources\wss.en-US.resx)
2. AccessDenied.aspx (from C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS)
Note: Please keep the Original file as a backup
CSS:
<style type="text/css" >
BODY #s4-simple-card H1 {margin-bottom:10px; color:#5b4b3e ; font-size:2em; font-weight:normal;padding-top:3px}
.ms-sectionheader {font-family: Verdana, Arial, sans-serif; color:#595959; font-size:2em }
.ms-descriptiontext {text-align:left; font-family:Verdana, Arial, sans-serif; color:#3f3f3f;font-size:10pt}
A:link, .ms-descriptiontext A:visited, .ms-descriptiontext A:hover { color:#0072BC; font-weight:bold; text-decoration:none; }
.s4-simple-iconcont { z-index:2; background-image: url('/_layouts/images/setcredentials_32x32.png'); HEIGHT: 60px; TOP: 10px;
background-position:left center; background-repeat: no-repeat; }
.s4-simple-iconcont img {display:none;}
</style >
Monday, March 7, 2011
How to Control Hyper Link Attributes to Open In a New Window
Wondering how to control the Hyper Link control behavior! Like STYLE, OPEN , SET FOCUS & ATTRIBUTES
Current project requirement to open the Hyper link with specific browser attributes like With Scroll bar, No Menu bar, Specific Window Position, Height & Width.
Achieved with Java Script as shown below code:
string strURL = "http://rajadandu.blogspot.com/";
//Create Hyper Link
HyperLink h = (HyperLink)e.Row.FindControl("ConfHlink");
// Setting Style
h.Style["margin-left"] = "5px";
//Setting default Hyper Link Navigation to NULL
h.NavigateUrl = "javascript:void(null);";
//Hyper Link Display string
h.Text = "Opening With Controlled Hyper Link";
//Java Script with Open Window with attributes
//Then at last Set Focus
h.Attributes["onclick"] = "javascript:window.open('" + strURL + "','','scrollbars=yes,menubar=no,height=430,width=700,top=0,left=0,resizable=yes,toolbar=no,location=no,status=no'); window.focus();";
Current project requirement to open the Hyper link with specific browser attributes like With Scroll bar, No Menu bar, Specific Window Position, Height & Width.
Achieved with Java Script as shown below code:
string strURL = "http://rajadandu.blogspot.com/";
//Create Hyper Link
HyperLink h = (HyperLink)e.Row.FindControl("ConfHlink");
// Setting Style
h.Style["margin-left"] = "5px";
//Setting default Hyper Link Navigation to NULL
h.NavigateUrl = "javascript:void(null);";
//Hyper Link Display string
h.Text = "Opening With Controlled Hyper Link";
//Java Script with Open Window with attributes
//Then at last Set Focus
h.Attributes["onclick"] = "javascript:window.open('" + strURL + "','','scrollbars=yes,menubar=no,height=430,width=700,top=0,left=0,resizable=yes,toolbar=no,location=no,status=no'); window.focus();";
Thursday, March 3, 2011
Open PDF makes you save!!
After few Hrs of research find out that this particular setting will now open’s .PDF directly in IE; by default is “Strict” which prompts the user for file download.
Step-By-Step:
You can fix this by navigating in to central admin
Application Management >> Manage web application
Now choose your web application (select the row) which makes ribbon to be active
and you will see general settings (in enabled mode) Now choose general settings from the drop down
find he Browser File Handling section by default it's strict, change it to Permissive click ok and you are done!!
Step-By-Step:
You can fix this by navigating in to central admin
Application Management >> Manage web application
Now choose your web application (select the row) which makes ribbon to be active
and you will see general settings (in enabled mode) Now choose general settings from the drop down
find he Browser File Handling section by default it's strict, change it to Permissive click ok and you are done!!
Tuesday, December 28, 2010
Remove Title Header from Webpart
Add this stylesheet elements to the page by using content editor webpart
<style type="text/css">
.ms-viewheadertr {
DISPLAY: none
}
.ms-vhltr {
DISPLAY: none
}
Subscribe to:
Posts (Atom)









