Archive for category Programming

WSPBuilder: How to enable custom workflows in existing project

 I had an old WSPBuilder project and I wanted to add workflow to it. The old project was created with WSPBuilder project template and with .Net Framework 2.0.

For people who are not interested in my strugle with this problem, skip these first 12 steps :)  For others, these are the steps I had to go through:

  1. I tried adding WSPBuilders Sequential Workflow Feature workflow directly to the project. It worked nicely.
    • After that I got three reference warnings (System.Workflow.Activities, .ComponentModel and .Runtime)
  2. I had to change target framework from 2.0 to 3.5. (Right click on project -> properties -> Target Framework). After that the references worked.
  3. I opened the workflow feature to designer mode and was greeted with these two nice messages
    • The service ‘System.Workflow.ComponentModel.Compiler.ITypeProvider’ must be installed for this operation to succeed. Ensure that this service is available.
    • The service ‘System.Workflow.ComponentModel.Design.IIdentifierCreationService’ must be installed for this operation to succeed. Ensure that this service is available.
  4. After some googling  Binging I found out that I needed to add more project type GUIDs to my *.csproj file.
    • Right click on project -> Unload project. Right click on project -> Edit *.csproj
    • Change the key <ProjectTypeGuids> to the following line
    • <ProjectTypeGuids>{F8810EC1-6754-47FC-A15F-DFABD2E3FA90};{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    • Right click on project -> Reload project
  5. Yeah, now I could edit the workflow in designer!
  6. I drag-and-dropped few tasks to the workflow, tried building it and it was good! I was already very excited to get this thing working.
  7. Deployed the solution to MOSS. Right click on project -> WSPBuilder -> Build WSP. Right click on project -> WSPBuilder -> Deploy.
  8. Added workflow to list and created new item. Nothing happened…
  9. Checked the workflow status and reviewed the logs to find these messages
    • From workflow status: Failed on start (retrying)
    • From MOSS logs: Engine RunWorkflow: System.Workflow.ComponentModel.Compiler.WorkflowValidationFailedException: The workflow failed validation
  10. After some more Binging found out that I also have to add some target-files (what every those are…)
    • Right click on project -> Unload project. Right click on project -> Edit *.csproj
    • Add the following new the key under the existing <Import Project=”$(MSBuildBinPath)\Microsoft.CSharp.targets” />
    • <Import Project=”$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets” />
    • Right click on project -> Reload project
  11. Build, deploy and have fun with your workflow!

And here is the same info in a nutshell:

  1. Change the projects target framework to 3.5
  2. Unload your project and modify your *.csproj file
  3. Change the project type GUIDs to this
    • ProjectTypeGuids>{F8810EC1-6754-47FC-A15F-DFABD2E3FA90};{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
  4. Add this line under the existing <Import Project=”$(MSBuildBinPath)\Microsoft.CSharp.targets” /> key
    • <Import Project=”$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets” />
  5. Reload project, build, deploy and enjoy!

Testing It Out: Taskbar Progressbar

This new feature is adds a great value for users, because now one does not need to keep the program visible to see the progress of any process (Report, web service call, download etc…) This feature is implemented already at least in the Internet Explorer 8 (Windows 7 version) and the file explorer (copying/moving).

Using the Windows7APICodepack to implement this feature is very easy and fast task. Here’s an example:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
using Microsoft.WindowsAPICodePack.Taskbar;
 
namespace TestingStuffOut
{
    public partial class Form1 : Form
    {
        Timer timer;
        int value;
 
        public Form1()
        {
            InitializeComponent();
 
            timer = new Timer();
 
            timer.Enabled = true;
            timer.Interval = 250;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
 
            progressBar1.Style = ProgressBarStyle.Blocks;
            progressBar1.Minimum = 0;
            progressBar1.Maximum = 100;
            progressBar1.Step = 1;
 
            value = 0;
        }
 
        void timer_Tick(object sender, EventArgs e)
        {
            // Reset the counter when it reaches maximum
            if (value == progressBar1.Maximum) value = 0;
            else value += 10;
 
            progressBar1.Value = value;
 
            // Here's the Taskbar Progressbar part
            TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
            TaskbarManager.Instance.SetProgressValue(progressBar1.Value, progressBar1.Maximum);            
        }
    }
}

And the example looks like this:

Normal mode

Normal mode

Error mode

Error mode

Paused mode

Paused mode

There was also a indeterminate mode (continuous), but I did not have time to test it also (means, I did not get it to work after one try and it’s very late :) )

Be sure to check out other parts of the “Testing It Out” series from the series starting page!

Testing It Out: Developing for Windows 7 with C#

I don’t do much pure Windows development. I’m more of a sharepoint guy myself, but these new Windows 7 features got me to boot up my visual studio and start testing these features out. When I started searching information about these features and using them in my programs, I found out that there is an API code pack for .NET Framework, because these features are not yet implemented directly to it.

Things to do before you can use these new features through API code pack:

  1. Download the API code pack from codeplex
  2. Unzip the WindowsAPICodePack-archive
  3. open the solution WindowsAPICodePack with Visual Studio and Build it
  4. Get the DLL-files from from each project folder and copy them somewhere safe
  5. Add reference to the DLL you need in your Visual Studio project

I’ll update a list of “Testing It Out” series here:

Visual Studio 2010 & .NET Framework 4.0 Beta 1 available

Downloads currently available only for MSDN users, but non-MSDN users will be able to download the packages on wednesday!

Info about the new features and download links can be found here.

Programmatically browse and get permissions from sharepoint site

I was “ordered” to go through hundreds of pages and collect permissions from them to create document of current user permissions for auditing. I was too lazy for that and wrote this piece of code that prints the sites name, url and permissions to console and then continues to go through all the sites under the starting site. You can also save the output to a file when running the executable from command line with the pipe command “program.exe > output.txt”.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
 
class Program
{
static void Main(string[] args)
{
try
{
using (SPSite siteCollection = new SPSite("http://localhost"))
{
using (SPWeb root = siteCollection.OpenWeb("SiteA/"))
{
string indent = string.Empty;
Console.WriteLine(indent + "-----------------------");
Console.WriteLine(subsite.Title + "\t" + subsite.Url);
Console.WriteLine(indent + "-----------------------");
writePermissionsFromSite(root, 1);
WriteSubSites(root, 1);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.StackTrace);
}
}
private static void WriteSubSites(SPWeb root, int depth)
{
string indent = string.Empty;
for (int i = 0; i &lt; depth; i++)
{
indent += "\t";
}
foreach (SPWeb subsite in root.Webs)
{
Console.WriteLine(indent + "-----------------------");
Console.WriteLine(indent + subsite.Title + "\t" + subsite.Url);
////Console.WriteLine(indent + subsite.Title);
Console.WriteLine(indent + "-----------------------");
writePermissionsFromSite(subsite, depth + 1);
if(subsite.Webs.Count &gt; 0)
{
WriteSubSites(subsite, depth + 1);
}
}
}
 
private static void writePermissionsFromSite(SPWeb subsite, int depth)
{
string indent = string.Empty;
for (int i = 0; i &lt; depth; i++)
{
indent += "\t";
}
 
if (subsite.Permissions.Inherited)
{
Console.WriteLine(indent + "P: inherited");
}
else
{
string roles = string.Empty;
 
foreach (SPRoleAssignment permission in subsite.RoleAssignments)
{
roles = string.Empty;
foreach (SPRoleDefinition role in permission.RoleDefinitionBindings)
{
 
roles += role.Name + "; ";
}
 
Console.WriteLine(indent + "P: " + permission.Member.Name + " - " + roles);
}
}
}
}