AWG Blogs

Thursday, December 13, 2012

Testing Email in SharePoint Dev Environment

Tried this. Installing local dummy SMTP not possible. Finally just configured the local SMTP Virtual Server in IIS 6.0 Manager, setting the FQDN of the local server in Advanced Delivery, leaving Smart host empty. Then in used the local server for Outbound SMTP server in CA Outgoing E-Mail Settings.

Try adding a user to a group and leaving send email checked, and, bingo, email appears in c:\inetpub\mailroot\Queue.

Monday, December 3, 2012

Finding Collapsed Groups in DataGrid

This question came up here, which I found when searching a solution to same problem.

Here is some code that solves this issue:

            List<string> grpItems = new List();
            string groupby = "";
            foreach (var control in dataGrid1.GetVisuals().OfType<DataGridRowGroupHeader>())

                var tog = XamlUtils.FindVisualChild<ToggleButton>(control);
                var context = control.DataContext as CollectionViewGroup;
                string nm = context.Name.ToString();
                bool? chk = tog.IsChecked;
                if (chk != null && (bool)chk)
                groupby = control.PropertyName;

The methods in XamlUtils are FindVisualChild and GetVisuals which can be found at and respectively.
Note: To get this to work, for some reason, it required removal of any filters on the PagedCollectionView.

Thursday, November 1, 2012

GetListItemChangesSinceTokenAsync and Paging

It's possible to page with GetListItemChangesSinceTokenAsync. For instance, if the result returns a ListItemCollectionPositionNext value, you know there are more results.

When make the call to retrive those results however, you must set changeToken to null. When I inserted the changeToken in a query for more paged results, I got zero results, which may seem counterintuitive, but actually makes sense because adding a changeToken that implicitely pointed to the next result set would be redundant as ListItemCollectionPositionNext already indicates this.

Monday, October 1, 2012

Reproducing "The user does not exist or is not unique"

If you get this error, you may need to ensure the AD account exists:

The user does not exist or is not unique. at Microsoft.SharePoint.Library.SPRequestInternalClass.UpdateMembers(String bstrUrl, Guid& pguidScopeId, Int32 lGroupID, Int32 lGroupOwnerId, Object& pvarArrayAdd, Object& pvarArrayAddIds, Object& pvarArrayLoginsRemove, Object& pvarArrayIdsRemove, Boolean bSendEmail) at Microsoft.SharePoint.Library.SPRequest.UpdateMembers(String bstrUrl, Guid& pguidScopeId, Int32 lGroupID, Int32 lGroupOwnerId, Object& pvarArrayAdd, Object& pvarArrayAddIds, Object& pvarArrayLoginsRemove, Object& pvarArrayIdsRemove, Boolean bSendEmail)

To reproduce (in MOSS 2007):
-  Add Domain\user to AD and "Start full import" in User Profiles and Properties
- Login as user to a site collection site (assuming nt authority\authenticated users is added to default members groups)
- As user add an item to any list so that the user then appears under Peoples and Groups: All People for that site collection
- Delete user from AD and "Start full import"
- Try adding the user to a Site collection group, e.g. Members. The user will be found in the people picker but the above error occurs when you try to add user to group.
- If you re-add the exact same user (same username) to AD and do full import, the problem resolves and can add user to Members now.

Note: to avoid confusion, should probably perform "Delete Users from Site Collection" from People and Groups: All People, whenever user is removed from AD. Still looking for a way to automate this...

Monday, September 17, 2012

Debugging Silverlight to SSL'd SharePoint .asmx from VS

As explained here, there are a few steps you need to take to enable this scenario, i.e. to get around:

An error occurred while trying to make a request to URI 'https://machinename/_vti_bin/Lists.asmx'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Copy the following files to C:\inetpub\wwwroot\wss\VirtualDirectories\443: crossdomain.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- The file must be configured to allow access to the service from any other domain, 
or it is not recognized by Silverlight 4.
Save the crossdomain.xml file to the root of the domain where the service is hosted. 
If, for example, the service is hosted in, 
then the file must be located at
<!DOCTYPE cross-domain-policy SYSTEM 
  <allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
<?xml version="1.0" encoding="utf-8" ?>
      <allow-from http-request-headers="*">
              <domain uri="http://*"/>
              <domain uri="https://*"/>

        <resource include-subpaths="true" path="/"></resource>
Note the subpaths="true"! Then open https://machinename/clientaccesspolicy.xml in browser (BTW verify its wellformed xml), accept the security warning, then click Certificate Error, View Certificate, then Install Certificate..., Next, then "Place all certificates in the following store", select "Trusted Root Certification Authorities", OK. After that, you should be able to F5 your Visual Studio 2010 Silverlight 5 app, and load your data from the SSL enabled Sharepoint 2007 web service. Ref1, ref2

Sunday, September 9, 2012

Set ClickMode to Press to Avoid Losing Click Event in DataGrid Column But Note Caveats

For some reason, I was losing the click event for a button in a DataGridTemplateColumn; i.e. the click event (and associated command) would not fire after editing another cell and immediately clicking the (delete) button in the far left column. Setting the ClickMode to Press (rather than the default of Release) appears to fix the issue; i.e. once that is done, the event fires, and I do not have to click Delete twice. There are a couple of steps to take in addition if the DataGrid is bound to a PagedCollectionView that you intend to Refresh() immediately, i.e. within the called Command. These are so as to avoid the error:
An exception of type 'System.InvalidOperationException' occurred in System.Windows.Data but was not handled in user code

Additional information: 'Refresh' is not allowed during an AddNew or EditItem transaction.
1) Add a GotFocus="Button_GotFocus" to the event with method:
        private void Button_GotFocus(object sender, RoutedEventArgs e)
            dataGrid1.CommitEdit(DataGridEditingUnit.Row, true);
Evidently, GotFocus fires before Click here, so it is the place to exit Edit mode.
2) Wrap the pagedCollectionView.Refresh() call in an asynchronous call:

    () =>
Evidently, the asynch call delays the refresh long enough so that the row can exit edit mode. These are workarounds that signal a compromise with MVVM and elegance in general, but until I find a better solution, it is what it is.

Use Explicit Binding to Force Update on TextChanged

If you have a TextBox inside a DataTemplate in a DataGrid, and want any TextChanged event to update the binding, set Mode=TwoWay, UpdateSourceTrigger=Explicit on the binding or else you will get an error:
"Operation is not valid due to the current state of the object."

More Notes:

Since this is an Explicit binding, you will need to hook to the event using a behavior such as Prism's UpdateTextBindingOnPropertyChanged. But since that has been made obsolete in Silverlight 5 you will need to get the class itself from the Prism code and add it to your project manually and then attach that like so:
                                <TextBox Height="23" HorizontalAlignment="Left"  
Name="textBox1" VerticalAlignment="Top" Width="120" 
Text="{Binding Invmprop, Mode=TwoWay}" >

                                        <local:MyUpdateTextBindingOnPropertyChanged />
Why is it obsolete? Because Silverlight 5 introduced UpdateSourceTrigger=PropertyChanged, which works fine in uncontained textboxes but not when they are in DataGrids (or so I've observed), so for those in DataGrids, I had to perform the above workaround.

Thursday, August 23, 2012

Add Change Order Action Menu Item

By default only the Links list type has this menu item in SharePoint 2007. It can be added to any other list though through the web services API, specifically updating the "Ordered" field property to True. See

Once that's done, just edit the View properties (including the anonymous views from any web parts) and set "Allow users to order items in this view." Doing so will change the order shown to that of the built-in Ordered lists property, which is what is updated via the (now shown) Change Order action menu for the view.

Here is an adapted sample console app:

class Program
        static void Main(string[] args)
            Console.WriteLine("Property Editor - v.0.1");
            Console.WriteLine("Enter the URL of the Lists web service");
            string url = Console.ReadLine();
            Console.WriteLine("Enter the Display name of your list, e.g. My List");
            string listname = Console.ReadLine();
            Console.WriteLine("Enter the list property (e.g. Ordered)");
            string property = Console.ReadLine();
            Console.WriteLine("Enter the property value (e.g. TRUE)");
            string propertyValue = Console.ReadLine();

            Web_Reference_Folder.Lists listService = new Web_Reference_Folder.Lists();
            listService.Credentials= System.Net.CredentialCache.DefaultCredentials;
            listService.Url = url;

            XmlDocument xmlDoc = new System.Xml.XmlDocument();

            XmlNode ndProperties = xmlDoc.CreateNode(XmlNodeType.Element, "List", 

            XmlAttribute ndOtherAttrib =
                property, "");
            ndOtherAttrib.Value = propertyValue;

                XmlNode ndReturn =
                    ndProperties, null, null, null, 


            catch (Exception ex)
                Console.WriteLine("Message:\n" + ex.Message + "\nStackTrace:\n" + 

Saturday, August 18, 2012

Compiling MD5summer in XE2

- Download md5summer.tar.gz from and extract all
  - Alternately get source (v1.2.0.05) from
- Download from
- Perform installation of ShellShock per the readme.txt, i.e.
  - add the tpshellshock_1_02_2011-09-08\source directory to XE2's Tools Options, Delphi Options, Library Path
  - open .packages\Delphi XE2\ShellShock Delphi XE2.groupproj in Delphi XE2
  - Right click on K102_R160.bpl and compile
  - Right click on K102_D160.bpl and install
- If reopening IDE, may need to do Component, Install Packages, then add
c:\Users\Public\Documents\RAD Studio\9.0\Bpl\K102_D160.bpl
- Download and install the author's components at ; also add library ref.
- Open md5summer.dpr to load project
- Compile and run

Note, if you choose not to install the author's components, you will need to make a few edits:
- To remove About components functionality
  - open u_About.pas and edit code: remove or delete all references to "Maze" and "Rect"
  - right click (RC) md5summer.exe and View Source, then comment out Application.CreateForm(TAbout, About)
- Open u_DoMD5s.pas and comment out these lines:
  - BatchGauge: TGauge;
  - FileGauge: TGauge;
  - Remove "Guage" from uses
- Open u_DoMD5s.dfm
  - drag two TGauge's from Samples in the Tool Palette to the form under Batch and File labels
  - name the top one BatchGauge and the bottom one FileGauge
- in u_DoMD5s.pas, search and replace all "Gauge.Position" with "Gauge.Progess"

Thursday, August 2, 2012

Logic for Viewing 2D Data in 3D

 Logic for Viewing 2D Data in 3D
Do with groupings of a unit (grouping function g) as x axis and observee in y axis. (Note: the fourth dimension would be grouping of groupings, i.e. higher order grouping functions as possible inputs.) Cell(x,y) equals the function of data items h(f(),g(),v,t(y,z,w) where y=y1) -- in our case, given y1 and grouping function g, lookup z for record that matches f(g(w)) -- below, for y1=observee1, 1.1 and 1.2 could be grouped into group with key v=1, i.e. g(v,t)={1.1,1.2}, then f(g(v,t))= max of {1.1,1.2} or 1.2, so return value is b == cell(x,y)

sample data:
(y)                (z)   (w)
observee1     a     1.1
observee1     b     1.2
observee1     c     2.1
observee2     a     2.1
observee2     a     1.1

Friday, July 6, 2012

"Specified view is invalid" error when transferring .webpart

I couldn't figure out why SharePoint would produce ASP.NET error when importing a previously exported .webpart. The quick way to resolve it is to remove the ViewFlag element or set it to 0 in the .webpart file. But I found that when I do this the web part does not set ctx values, such as httpvdir. One workaround is to use Server variables rather than CAML variables in the .webpart's ParameterBinding value. I could also open the page in SPD, and make a minor change and save it, which fixes the problem. But I still need to determine what is causing the issue. (BTW, what does ViewFlag, or its absence, have to do with the issue, and what do the ViewFlag values mean anyways? No-one knows apparently).

I finally reproduced the issue in a simple case:
In SourceSiteCol, create a plain doc library and set ContentTypesEnabled to true ("Allow management of content types").
Save as list template. Copy this to DestSiteCol List template gallery.
On DestSiteCol subsite, create a list based on the uploaded list template.
In a web part page on this subsite, add a ListViewWebPart based on the created list. In SPD, convert it to a DataFormWebPart.
Export it as a .webpart. Then import into another web part page on the same site; the error occurs. Disabling Content type management for the created list makes the error go away. So the problem has something to do with Content Types...

At any rate, when transferring lists and their web parts to other sites, can edit the .webpart as follows:
Look for SelectParameters and change the Parameter with ListID to have ListName, and set its DefaultValue to the current display name of the target list (note, if the display name changes, your web part will break, and you'll have to fix the name in the XSLT).
Remove the  Update, Insert, and Delete params see (
Set TitleUrl property to the URL of the default view
Set the Title property to the intended title of the web part

Friday, June 15, 2012

Biological Architecture of Software Applications

Organs communicate through the medium of interstitial fluids, i.e. the environment of the body. The sun communicates with the open system of Planet Earth through an environment of space. When you look around self-sustaining systems communicate through indirect mediums. Why should software architecture be any different?

The easiest-to-develop and most self-sustaining software is done, I propose, through a combination of the Observer design pattern and Environments. These Environments are the Observables that trigger events whenever properties are set; Observers (like cells and enzymes) subscribe to those property initializations of interest and may set further properties on their Environment. Environments may subscribe to the property change events of other Environments and so forth. This is a more natural way to design implement software. DCI on steroids if you will. Makes DDD look rather stodgy by comparison....

Monday, May 21, 2012

Secondary Lookup Column in SP2007?

There's UI support in 2010

Stefan Stanev found out it's possible to rig SP2007 to do the same thing, sort of (see

The catch is deleting the field will give error Exception calling "Delete" with "0" argument(s): "One or more field types are not installed properly. Go to the list settings page to delete these fields."

I noticed you get the same error if attempting to delete Created_x0020_Date once AllowDeletion is set to True. So it appears the issue is widespread with regard to lookup columns that contain the FieldRef attribute.

My only concern is what happens when upgrade occurs.

Monday, April 30, 2012

Middleman Pattern

The DCI paradigm, specifically the canonical example of the account transfer seems unnatural. If I'm not mistaken, in most business domains the act of transferring resources between entities is performed by a middleman entity. Behavior is no more injected into entities than are entry-level checking account clerks trained on the spot to make transfers to investment accounts (imagine this is a bank in the pre-computing days).

So I propose the "Middleman Pattern." The following is an example. Note: the example could be abstracted in that concrete classes could be decoupled via interface implementation and dependency injection.

Edit: See also suggestion of "money transferrer" at

Tuesday, April 24, 2012

SharePointMVC Note

When following the Deployment.docx, the instructions say to put the DLLs in the SharePoint website _app_bin. Well, I had to also put the web app DLL in the SharePoint website bin folder to get it working; otherwise I'd get the error: Could not load type 'SampleWebApplication.xxxxxx'.   at System.Web.UI.TemplateParser.GetType(String typeName, Boolean ignoreCase, Boolean throwOnError)
   at System.Web.UI.TemplateParser.ProcessInheritsAttribute(String baseTypeName, String codeFileBaseTypeName, String src, Assembly assembly)
   at System.Web.UI.TemplateParser.PostProcessMainDirectiveAttributes(IDictionary parseData)

Sunday, April 15, 2012

UML Aggregation Vs DDD Aggregate

The same root term "Aggregate" in DDD does not correspond to the UML "Aggregation" notation (filled diamond).

DDD use of root term "Aggregate":
OrderLines have no reason to exist without their parent Order, nor can they belong to any otherOrder. In this case, Order and OrderLines would probably be an Aggregate, and the Order would be the Aggregate Root

Sunday, March 18, 2012

Force Post in .load method

The following code:
may produce the error in the Response as visible from the Console tab of Firebug: "Request format is unrecognized for URL unexpectedly ending in '/HelloWorld'."

This ASP.NET web service expects a POST. To force a POST change the code by adding a bogus object to the .load jQuery method:

Update: Actual fix is to edit the web.config, see comment by Lotas here.

Monday, March 12, 2012

Setting Theme in Feature Receiver

When provisioning web sites, the theme was not taking. To get it working I made the following change to RestoreWebProperties, which was generated by SharePoint Solution Generator.

string key = xWebProperty.Attributes["Key"].Value;
string value = xWebProperty.Attributes["Value"].Value;
//this does not work for __IncludeSubSitesInNavigation, use AllProperties instead
/* if (web.Properties.ContainsKey(key))
web.Properties[key] = value;
web.Properties.Add(key, value);
} */
//need explicit set, apparently setting via property bag does not effect update
if (key == "vti_themedefault")
catch { }

web.AllProperties[key] = value;


Note, get the theme key from TemplateID element in SPTHEMES.XML. Also do web.Update() instead of web.Properties.Update().

Friday, March 9, 2012

TFS Project Folders and Workspaces

In Source Control Explorer, one way to map separate folders to separate local paths, perhaps on a separate drive e.g., is to use Workspaces.

Do File, Source Control, Workspaces, Add Workspace. Name the Workspace as appropriate, e.g. "My Projects." Select the TFS project folder, and the corresponding Local folder. Click OK.

This way you can separate your local files on a separate local root folder, (e.g. c:\My Projects") from folders other team members own (e.g. mapping of c:\Other projects).

Sunday, February 26, 2012

Perl Map Chaining to Obtain Unique Subkeys

Say you have a file with contents:

AABB 7323|Jan 28, 2003|Random Data Here
YZZ 2852|Mar 3, 2007|Data Data
YZZ 2559|Aug 2, 2010|More Data
AABB 2383|Jun 1, 2011|Data Field Data

The following perl script can list the unique key types:


use strict;
use warnings;

my $filename = "testinput.txt";
open (ROWS, "<$filename");

my $delimiter = '\|';

my %values = map {split / /, $_ } keys %{{map { split $delimiter, $_, 2 } <ROWS>}};
my @uniques = keys %values;
print join ("\n", @uniques);

exit 0;

which outputs:


Note: when assign an array to a hash lvalue, the array elements are assign sequentially in key value pairs, since there's no such thing as hash context. see

Tuesday, February 14, 2012

Master Pages in Subsites

You may get "The system master page setting currently applied to this site is invalid. Please select a new master page and apply it" in _layouts/ChangeSiteMasterPage.aspx, when having set a subsite of a site collection (with publishing infrastructure enabled) to use a master page within the subsite relative _catalogs/masterpage/ folder. It appears MOSS 2007 publishing infrastructure does not fully support subsites utilizing master pages from subsite master page galleries, hence the error.

To avoid this error, ensure that every subsite in a site collection with Publishing Infrastructure enabled is using a master page that resides in the master page gallery of the root site.

Ironically, doing so however, causes another error in SharePoint Designer "The URL ../../_catalogs/masterpage is invalid" when editing the subsite in SPD. Therefore, it appears that editing subsites in site collections, that have Publishing Infrastructure enabled, in SPD is not supported.

Monday, February 13, 2012

Setting Default DisplayCategory for Create Site Page

In MOSS 2007, one way to have your template category selected by default when click "Create Site" from Site Actions when Office SharePoint Server Publishing is enabled is edit 12\TEMPLATE\LAYOUTS\EditingMenu\SiteAction.xml (Backup first!). Edit the ConsoleNode item whose action is "cms:CreateNewSiteAction" and ID is "wsaCreateSite." Add (or replace) two attributes:

Note, the IsSiteRelative attribute is required so that subsites don't get file not found errors.

Finally, recycle the app pool.

Another option that applies to site collections only is to edit _catalogs\masterpage\Editing Menu\CustomSiteAction.xml, adding the Console tags with custom content as needed.

Tuesday, February 7, 2012

Publishing Enabled on Root Site

I noticed that unless Office SharePoint Server Publishing is enabled on the root site in a site collection, subsites do not show the Pages Library as a "List Type" in the Content Query Tool Part, regardless of whether Publishing is enabled as site feature in the subsite.

I have not done exhaustive testing to see whether this is related to the initial site definition that was applied, but at any rate, this appears to be a bug (or "gotcha") in MOSS 2007.

Thursday, February 2, 2012

LookupColumn fields require no FieldRef?

That appears to be the case when writing the CAML for a custom field.

I asked the question as it concerns FileLeafRef on MSDN. We'll see if I get a response or pointed to some more documentation.

I did notice in
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\XML\FLDTYPES.XML that the definition for File has its InternalType set to Lookup, so maybe that's my answer.

What got me curious is observing that updates to my computed column via /_layouts/FldEdit.aspx caused the whole FileRefs element to be removed! I noticed that the doclib list continued to show the field, but the list did not. Presumably because the fieldref was not needed...

More questions along these lines:

Why is the FieldRef Name="Created" necessary in a custom computed "Name" field in a document library, but not in a custom computed "Title" field in a List?

How come <Column Name='Created_x0020_Date' /> causes "Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION)" YSOD, when clearly the documentation states that it should return an integer, since it's a lookup type.

Monday, January 30, 2012

"There is no Web named..." error

When setting up your web reference in Visual Studio 2008, you must enter http://server/sites/mysitecollection/mysubsite/_vti_bin/Lists.asmx?WSDL including the "WSDL" at the end! Or else, you will get this error in your inner exception, when attempting to access a list, using the GetList(listguidstring) method.

Sunday, January 29, 2012

Sharepoint PowerShell Shortcuts

Command to output sorted site columns:
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> set-variable -option constant -name url -value "http://servername/sites/teamsite/"
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> $site = new-object Microsoft.SharePoint.SPSite($url)
PS C:\WINDOWS\system32\WindowsPowerShell\v1.0> $site.rootweb.Fields | foreach { $fieldValues = @{ "Display Name" = $_.Title; "Internal Name" = $_.InternalName; "Value" = $site.rootweb.AvailableFields.GetFieldByInternalName($_.InternalName) }; New-Object PSObject -Property $fieldValues | Select @("Display Name","Internal Name","Value") } | Sort-Object -Property "Internal Name" | Out-GridView


see also:

Thursday, January 26, 2012


[MOSS 2007] Got the following error when I selected "Show items from the following list" and browsed to a doc lib whose display name contained a forward slash (/):
Cannot save the property settings for this Web Part. The list name is not valid. The list name should refer to a list within the specified site..."

So to workaround the inability of this SP component to recognize lists with forward slashes in them, I decided to try to filter by list ID under Additional Filters. No go again. I entered the list's QUID and no data was returned. This appears to be a bug as well.

So I settled for a Data Form Web Part hooked up to an XML Web Service configured in the Data Source Library: Port set to ListsSoap12, Operation: GetListItems; listName=GUID (including curly brackets). Had to tinker with the XSLT to get the display somewhat correct, e.g. to get the doc image to show, use <img src="/_layouts/images/{ddwrt:MapToIcon('',string(@ows_DocIcon))}"/>

Wednesday, January 18, 2012

Adapting the schema.xml

I wanted to add a new field to the base item content type -- i.e. content type ID 0x01. I also wanted to change the display name of title. This is what worked for my schema.xml.

Copy the Schema.xml from FEATURES\CustomList\CustList to my Feature folder named after the Name attribute of the ListTemplate element.

Comment out both ContentTypeRef elements.

Create a ContentType element that likes like:
Group="List Content Types"
Description="Create a new list item.">
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
DisplayName="My Title"
<FieldRef ID="{AA242460-9794-4d45-A726-938D1B8B7D72}"
Name="My Added field"



NOTE the ContentType ID structure: follows the GUID method from MSDN, MAKE sure to remove any hyphens!!!

Add all modified fields to the Fields element, including Title, LinkFilenameNoMenu, and LinkTitle. You can get samples from a schema.xml that you copy from a list in SharePoint Manager.

Adjust View BaseViewID="1" as needed.

Wednesday, January 11, 2012

SharePoint Workflows on 64bit server

This is a quick start on how to get a functioning workflow compiled, installed, and running to completion. It will simply log a message to the workflow history; that's it.

Assumes Visual Studio 2008 is installed on Windows Server 2003 64bit with WSPBuilder.

File, New Project, WSPBuilder Project with Workflow

Right-click project in Solution Explorer and choose Workflow, Sequential Workflow (code) - note: I tried using Sequential Workflow with definition expressed as Xaml and user code in a separate code file, but I got errors such as "RunWorkflow: System.Workflow.Activities.EventDeliveryFailedException: Event "OnWorkflowActivated" on interface type "Microsoft.SharePoint.Workflow.ISharePointService" for instance id "405ff0ae-d08d-41b8-ab69-be69ae4ccde1" cannot be delivered. ---> System.Workflow.Runtime.QueueException: Event Queue operation failed with MessageQueueErrorCode QueueNotFound for queue 'Message Properties Interface Type:Microsoft.SharePoint.Workflow.ISharePointService Method Name:OnWorkflowActivated CorrelationValues: '. "

Drag a onWorkflowActivated control onto the designer
Set its CorrelationToken property to anything, e.g. "mytoken"; then expand CorrelationToken and for OwnerActivityName, choose Workflow1 (e.g.)

Drag a logToHistoryListActivity onto the canvas under the onWorkflowActivated1 control.
Double click its MethodInvoking property, and enter the following code into the body of the method: var workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties();

this.logToHistoryListActivity1.HistoryOutcome = "Here is a comment " + workflowProperties.InitiationData;

Build Solution

Right click property and choose WSPBuilder, Copy to GAC

Create a folder called MyLoggingWorkflowFeature under C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES\

Create two xml files in this folder:
<?xml version="1.0" encoding="utf-8"?>

<Feature Id="genkey id here"
Title="Workflow to create a log something to history"
Description="Logs something to history"
<ElementManifest Location="workflow.xml" />


<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="">
Name="New Task Workflow"
Description="Creates a new task"
Id="yourId here from genkey tool"
CodeBesideAssembly="NewTaskWorkflow, Version=, Culture=neutral, PublicKeyToken=yourkeytokenhere"