Skip to content

SharePoint Tutorials

LearnVu (SharePointHosting) has posted a huge number of SharePoint tutorials at http://www.sharepointhosting.com/video_tutorials.html. [Sorry, the page was removed.]

Thanks to P. Erol GIRAUDY for posting this and Lawrence Liu for the nudge to make them more visible.

crack

The Email Foundation is Cracking

In the old days, before spam had taken hold, before the Internet had become something that a vice president wanted to claim credit for creating, and before the media became so enamored with the latest goings on in CyberSpace, email was reliable.  It was more reliable than the US Post Office.  It was a pleasure to get email.

I can remember that I used to be thrilled when I dialed up my modem and opened my POP mail client – or further back logged into a Unix Shell account and got my mail.  It was a thrill to be able to speak with friends who were far away but who had somehow found their way to the Internet.

Those days are long gone.  The foundation of email as we know it is cracking and we’re all seeing it.  Here’s what’s happening that we may not be seeing.

Second Order Effects of SPAM

If you ask anyone about unsolicited commercial email, SPAM, you’ll hear about all of the lost time. You’ll hear about the latest in body part enhancements, the newest investment opportunity, or perhaps about a poor man in Nigeria who needs someone to accept billions of dollars.  SPAM is an annoying and unfortunate reality of email on the Internet today.

If you read any statistics about email you’ll quickly realize that SPAM is growing at a rate disproportional to the overall growth of email.  My own incoming mail is approximately 50% spam, 2% viruses, and who knows how much useless mail.  The estimates for corporate email system is that more than 80% of the mail coming in is SPAM.

These sobering statistics have forced nearly every organization to take actions to defend against it.  Real-time Blacklists, heuristic scanning, pattern matching, reverse DNS lookup, and other techniques are layered together to form a defense from SPAM.

This has created a doubt that your message has made it through.  Suddenly the second order effect of SPAM is raising its ugly head.  Instead of having absolute trust that your message will be delivered to the other end you have to consider that your message may have been caught by their SPAM filters.  You have to consider that your SPAM filters may have caught their response.

It’s an unfortunate reality that something that we could once trust implicitly now must be considered fallible.  We must accept that our messages aren’t guaranteed to make it to the other end any longer – not that they ever really were but we may have felt reassured more than we are today.

It seems almost routine now that I hear about messages that don’t make it through because of SPAM filters.  Just this week I had a message that was definitely caught in a SPAM filter.  I myself am starting to realize that I can no longer rely upon email without question.  I must consider the need to follow up.

A Million Straws

Perhaps the way you’re seeing the foundation crack isn’t in the loss of messages but rather in the delay of messages.  It used to be that you could talk to a support technician and send them a file.  Almost before you finished saying the words “The file is on its way” the file was already in the recipients’ inbox.   Today I’m routinely faced with the response “I’m still waiting on your email message.”  The delay in mail systems is getting to be greater.  Even with faster network connections, faster mail servers, and more advanced mail programs, the delay problem is getting worse.

The overall volume of mail that organizations deal with today would have been inconceivable ten years ago.   PostIni (www.postini.com), a mail-forwarding organization, estimates that it processes 1 billion messages every day.    The Congress Online Project (www.congressonlineproject.org) reported that mail destined for congress increased from 20 million messages in 1998 to 48 million messages in 2000 – and that the load on the servers has created delays of hours – and sometimes days in the delivery of messages.

Is it any wonder why it takes longer for messages to reach the destination today than it did even a few short years ago.  Add to the layers of protection that we now must have to protect against spam, an immense increase in overall volume and it’s not hard to see why we may have to wait several minutes before messages reach their intended destination.

However, this is time that is wasted.  An efficiency we picked up due to technology is the ability to nearly instantly show someone on the other end of the line what we were seeing.  We could attach the corrupted file, the log file, or whatever and it would be whisked silently and quickly away to the destination.  No longer.  It’s not the Pony Express any longer.  It’s your favorite airline’s luggage handler.  Pieces of eMail that are lost or delayed are climbing.

Conclusion

So what does this mean?  It means that the next time you are confronted with someone asking about what the harm is in SPAM messages.  Think beyond the amount of time it takes to read them – think beyond the cost of the internet connectivity.  Think about the costs of the whole war on SPAM.   Think about lost messages and delayed messages and what it does to further reduce the time that we have for our professional careers, our personal lives, and our community.

Custom Master Pages and Site Definitions in WSSv3 (and MOSS2007)

Master pages are a very powerful new feature in WSSv3 (and MOSS2007 by extension).  They allow you a level of control that just wasn’t possible in WSSv2.  However, with anything new there can be some misunderstandings.  I wanted to share a few things that I’ve discovered while trying to get my custom master pages working.

First, we’re creating a new site definition here so let’s start with that.  Todd Baginski’s post “HOW TO: Creating a custom Site Definition in MOSS 2007” is a good walkthrough.  Next we need a custom master page.  A copy of the default.master from …12\TEMPLATE\GLOBAL makes a good starting point.  Drop that off in your new site definition directory.

Now it’s time for some modifications, first, you may want to rename your default.master you copied into your site definition.  You can use custom.master if you want – or any other name, it doesn’t matter.  Next, open your default.aspx file and change the MasterPageFile attribute on the top line to read “~masterurl/custom.master” – use this string even if your custom master page isn’t named custom.master.  SharePoint does a string replacement of this string with the value contained in the CustomMasterUrl property of the site (SPWeb).  Save the default.aspx file and repeat the process for defaultdws.aspx.  (If you want to know more about the string replacement you can look at the “Customizing Master Pages in Windows SharePoint Services” SDK entry.)

Now we need to connect that to your site definition.  That’s in your ONET.XML in the XML subdirectory of the site definition.  Locate the Configuration node.  Add a CustomMasterUrl attribute and set it to “_catalogs/masterpage/mypage.master” where mypage.master is the actual name that you gave your new master page.  Now in the Modules nodein the configuration add a new Module tag referencing a new module definition you’ll define in a second.  The node should look something like:

<Module Name=”CustomMasterPage” />

After the <Configurations> node/section there’s a module node section.  In this section add:

<Module Name=”CustomMasterPage” List=”116″ Url=”_catalogs/masterpage” RootWebOnly=”FALSE”>
<File Url=”mypage.master” Type=”GhostableInLibrary” IgnoreIfAlreadyExists=”TRUE” />
</Module>

Again, replace mypage.master with whatever you named your custom master page.

At this point you’re done.  You can save the files, do an IIS reset and use your site with a custom master page.

A few notes about the whole process:

1)      The “Customizing Master Pages in Windows SharePoint Services” SDK entry seems to indicate that you need to set both MasterUrl and CustomMasterUrl whenever you customize the master page – this isn’t correct.  You can simply modify the CustomMasterUrl if you wish.  This is a preferred approach for me because then you can change your default.aspx back to use a MasterPage of ~masterurl/default.master if you encounter issues with your custom master page.  Of course, if you do this your pages will need to reference ~masterurl/custom.master to get your custom master page.

2)      In the comments of Todd’s post “HOW TO: Creating a custom Site Definition in MOSS 2007”, Dan gives most of the information here – with a few extras.  One of the extra things that he includes is a <ListTemplate>.  If you include this node the site will work fine when created directly from a site definition, but it won’t work if you recreate the site from a site template.  For some reason, SharePoint ignores this node on creation from a site definition – but not when being recreated from a site template.  You’ll get some errors provisioning the global masterpage gallery in the ULS logs and a SharePoint File Not Found error.  However, the snipit works fine without the ListTemplate node.

Special thanks to Quang Sun who drew the PSS case I opened to get this all straightened out.

Fetching the indentity back from an insert with SQL server

It had been a while since I had to grab the identity of a record after an insert.  Most of the time I’m using stored procedures to do inserts and return it as the return from the procedure — but for a variety of reasons, I needed to do this with a direct insert statement.  The process is pretty simple once you get it down.  For instance, if you have a table with an ID (identity) field, and a name field which is named Areas, you might have something like this:

cmd.CommandText = string.Format(“INSERT INTO Areas(Name) VALUES(‘{0}’); SELECT SCOPE_IDENTITY()”,                    Manager.SQLSafe(_name));
_id = Convert.ToInt32(cmd.ExecuteScalar());

In this code cmd is a SqlCommand object and Manager.SQLSafe just makes the string safe for inclusion in SQL.  Finally the SELECT SCOPE_IDENTITY() is a replacement for @@IDENTITY which doesn’t have some of the side effects that @@IDENTITY has.

You have to convert the return value to get it into an integer because it’s returned as a decimal.

Solving “The process cannot access the file because it is being used by another process” in .NET

While working on a log parser (for SharePoint ULS logs ) I ran into a problem in trying to open the current file.  I got the “The process cannot access the file because it is beung used by another process” exception back.  After playing with the way the file was opened I was able to come up with a technique that would allow me to open the file and read from it.

Here’s the line of code to use:

FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

This will open the file even if the program is still logging to it.  It works great if you want to read whatever’s already written to the file.

blue pawn

Live Messenger/MSN Messenger doesn’t connect on Vista behind a SonicWall TZ170

Sometimes you run into a problem that’s really just too much to figure out.  It involves multiple groups, multiple vendors, and multiple headaches.  One of my recent challenges has been getting Live Messenger to work from Vista.

I built a new Vista Ultimate machine with the x64 release bits.  Everything was fine until I realized that none of my MSN messenger buddies ever appeared like they were online.  I dug a little and realized that I could login from the Windows XP system sitting next to me but Vista wouldn’t work  I’d get an error during the sign in process.  I opened a support case with SonicWall who told me that it was a Microsoft Windows problem – and oh by the way, they don’t support Vista yet.  They were seeing a TCP ReSeT from the client.  It was a client problem.

I travel out to Redmond, WA on business and guess what … my MSN contacts work fine from the vista box.  Now I’m really confused.  It works when the system is remote but not when it’s on my network.

I’m already frustrated as I try to understand why for firewall functionality the client OS mattered – however, I opened a case with Microsoft.  After fighting to get the issue landed in the Vista Networking queue instead of the MSN queue… we started working on the resolution.

The net of it – after dozens of hours wasted – was that I updated my SonicWall to the latest firmware (3.2.0.3-54e).  I then went in and UNCHECKED the option under Firewall-Advanced labeled  ‘Enable support for Windows Messenger’.  That’s right, I turned it off.  Unchecked it.  Said, I don’t want it.

Live Messenger fired up immediate on the Vista Machine.

Arg.  It should have been easier than this.

Special thanks to my friends in Microsoft PSS who stayed with me to help find the resolution.

[Keywords: Sonicwall, Windows Live Messenger, Error 81000306, Sudden disconnect Added 06-12-20]

 

Article: Open-Eyed Offshored Development

In the United States there is an array of responses when you mention the word offshoring.

Offshoring is the process where by less expensive resources are sought out from a different geography. It’s not a new concept. The industry has seen both successes and failures in the implementations of outsourcing. For some it creates solutions, and for others it creates headaches.

There is no one formula for success; however, there are a few key approaches that you can take to improve you odds for a successful implementation of outsourcing.

http://www.developer.com/design/article.php/3646336

InvalidOperationException “The event receiver context for Workflow is invalid” Problems with onTaskChanged in a SharePoint Workflow

If you’re dropping a onTaskChanged activity and you’re finding an event in the ULS like the following …

11/30/2006 08:56:04.12  OWSTIMER.EXE (0x05D4)                    0x0B48 Windows SharePoint Services    Workflow Infrastructure        72er Medium   System.InvalidOperationException: The event receiver context for Workflow is invalid.     at Microsoft.SharePoint.SPEventReceiverDefinition.ValidContext()     at Microsoft.SharePoint.SPEventReceiverDefinition.ValidReceiverFields()     at Microsoft.SharePoint.SPEventReceiverDefinition.GetSqlCommandToAddEventReceivers(IList`1 erds)     at Microsoft.SharePoint.Workflow.SPWinOESubscriptionService.CommitNewSubscriptions(Transaction txn, IList`1 erds)

The problem may no with the event receiver, rather that in the CreateTask activity you didn’t associate properties for TaskID, TaskProperties, or CorrelationToken.  Thus there’s no context for the event to call back to.

Adding CreateTask Activity to a SharePoint Workflow

Sometimes things aren’t as easy as they seem.  Adding a CreateTask activity to a SharePoint Workflow is one of those things.  Drag-and-Drop and you’re ready to go.  Not quite.  There are several things that you need to know about adding a CreateTask Activity.

First, you need to know about Correlation tokens.  Basically, the task needs a different correlation token than the workflow itself.   You can find the documentation for this in the SDK under Server Technologies\Windows SharePoint Services 3.0\SDK Documentation\General Reference\Workflows in Windows SharePoint Services\Workflow Development for Windows SharePoint Services\Workflow Development in Visual Studio 2005\Workflow Activities Overview\Correlation Tokens in Workflows.  You can also read Eilene Hao’s post on the SharePoint Team Blog titled “Developing Workflows in VS: Part 3 – Five Steps for Developing Your Workflow”.

Next, you have to do some manual manipulation of the code for the workflow to define the appropriate properties and get them setup for the activity’s use.   In the SDK documentation at Office solutions Development\SharePoint Server 2007\SDK Documentation\General Reference\Managing Enterprise Document Content\Workflows in Office SharePoint Server 2007\Walkthrough: Creating Office SharePoint Server 2007 Workflows in Visual Studio\Step 1: Create the Workflow there is a section “Adding and Configuring Workflow Activities\To add the CreateTask activity” which contains a suggestion for the properties to be set – and more importantly some code you’ll need to get the task to work correctly.

The net of it is that you must declare public fields tasked as a Guid – and get a new Guid in the value when the MethodInvoking is called.  You must also declare and new a Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties.  These must be assigned to the TaskId and TaskProperties of the activity respectively.

If for some reason you fail to do this you may see an error in the log like the following:

[Note: You don’t have to read through the following, it’s mainly included here so that it can be indexed so if someone is searching for the cause of the error they might find it.  Rlb]

11/29/2006 22:30:43.57 w3wp.exe (0x00C4)                       0x0C6C Windows SharePoint Services   Workflow Infrastructure                       88xr       Unexpected       WinWF Internal Error, terminating workflow Id# 4a62891e-f779-499c-86d1-a2362f461978

11/29/2006 22:30:43.58 w3wp.exe (0x00C4)                       0x0C6C Windows SharePoint Services   Workflow Infrastructure                       98d4      Unexpected       System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.NullReferenceException: Object reference not set to an instance of an object.     at Microsoft.SharePoint.Workflow.SPWinOETaskService.CreateTaskWithContentTypeInternal(Guid taskId, SPWorkflowTaskProperties properties, Boolean useDefaultContentType, SPContentTypeId ctid, HybridDictionary specialPermissions)     at Microsoft.SharePoint.Workflow.SPWinOETaskService.CreateTask(Guid taskId, SPWorkflowTaskProperties properties, HybridDictionary specialPermissions)     — End of inner exception stack trace —     at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)    …

11/29/2006 22:30:43.58*               w3wp.exe (0x00C4)                       0x0C6C Windows SharePoint Services   Workflow Infrastructure                    98d4      Unexpected       … at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)     at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)     at System.Workflow.Activities.CallExternalMethodActivity.Execute(ActivityExecutionContext executionContext)   …

11/29/2006 22:30:43.58*               w3wp.exe (0x00C4)                       0x0C6C Windows SharePoint Services   Workflow Infrastructure                    98d4      Unexpected       …  at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)     at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(Activity activity, ActivityExecutionContext executionContext)     at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)     at System.Workflow.Runtime.Scheduler.Run()

Or

11/29/2006 22:18:01.14 w3wp.exe (0x0D18)                       0x0AB0 Windows SharePoint Services   Workflow Infrastructure                       72ev      Medium               Value cannot be null.

11/29/2006 22:18:01.31 w3wp.exe (0x0D18)                       0x0AB0 Windows SharePoint Services   Workflow Infrastructure                       88xr       Unexpected       WinWF Internal Error, terminating workflow Id# b0474e92-3e38-443e-9ac1-c27afb1d20cf

11/29/2006 22:18:01.31 w3wp.exe (0x0D18)                       0x0AB0 Windows SharePoint Services   Workflow Infrastructure                       98d4      Unexpected       System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.ArgumentNullException: Value cannot be null.     at Microsoft.SharePoint.Workflow.SPWorkflow.GetReservedItemId(SPList list, Guid taskId, Boolean createNew)     at Microsoft.SharePoint.Workflow.SPWorkflowInstanceBase.GetReservedItemId(SPList list, Guid taskId)     at Microsoft.SharePoint.Workflow.SPWinOETaskService.CreateTaskWithContentTypeInternal(Guid taskId, SPWorkflowTaskProperties properties, Boolean useDefaultContentType, SPContentTypeId ctid, HybridDictionary specialPermissions)     at Microsoft.SharePoint.Workflow.SPWinOETaskService.CreateTask(Guid taskId, SPWorkflowTaskProperties properties, HybridDictionary specialPermissions)     — End of inner exception stack trac…

11/29/2006 22:18:01.31*               w3wp.exe (0x0D18)                       0x0AB0 Windows SharePoint Services   Workflow Infrastructure                    98d4      Unexpected       …e —     at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)     at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)     at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, Parame…

11/29/2006 22:18:01.31*               w3wp.exe (0x0D18)                       0x0AB0 Windows SharePoint Services   Workflow Infrastructure                    98d4      Unexpected       …terModifier[] modifiers, CultureInfo culture, String[] namedParams)     at System.Workflow.Activities.CallExternalMethodActivity.Execute(ActivityExecutionContext executionContext)     at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)     at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(Activity activity, ActivityExecutionContext executionContext)     at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)     at System.Workflow.Runtime.Scheduler.Run()

(These are located in the Universal Logging Service log at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\LOGS)

Article: SharePoint Governance, Part 2

Microsoft SharePoint technologies offer an immense amount of power for an organization, and harnessing this power is the goal of every business that installs SharePoint.  But adoption of SharePoint can get out of control without proper governance. In part two of this article, you’ll learn more about some of the issues that you should consider for a SharePoint technologies governance plan.

http://www.intranetjournal.com/articles/200611/ij_11_29_06a.html [Website removed]

Recent Posts

Public Speaking