Monday, June 27, 2011

Parallel Programming with C# and .NET Framework 4.0 - Shared-Memory Multicore

Everyday processor manufactures introduces highly advanced processors with multicores. Since multicores offers the advantage of carring out many programs simultaneously, Parallel Programming is becoming a major topic in the Software Industry. Since I am new to Parallel Programming and I have already started learning Parallel Programming, I thought to write some posts about Parallel Programming as I go forward with learning. So someone who is passionate about learning this interesting topic might get these posts helpful. I should mention that I am referring the book "Professional Parallel Programming with C# - Master Parallel Extensions with .NET 4 - 2010" by "Gaston C. Hillar" which is a Wrox Publication.

What is Parallel Programming?

Parallel programming is a form of computation in which many calculations are carried out simultaneously and by doing so large problems can often be divided into smaller ones, which are then can be solved in parallel ("concurrently").

Post 01. Shared-Memory Multicore

Now to speed up the processing power, Microprocessor manufacturers are adding processing cores instead of increasing their clock frequency. Most machines today have at least a dual-core microprocessor. However, quad-core and octal core microprocessors, with four and eight cores, respectively, are quite popular on servers, advanced workstations, and even on high-end mobile computers.

You can think of a multicore microprocessor as many interconnected microprocessors in a single package. All the cores have access to the main memory. Thus, this architecture is known as shared-memory multicore. Sharing memory in this way can easily lead to a performance bottleneck.

shared-memory multicore architecture

Multicore microprocessors has nicely designed architecture that offers more parallel execution, more overall throughput and most importantly it reduces the potential of having bottlenecks. Not only that multicore microprocessors uses less power and there by generates less heat. If you haven’t heard about this already Microsoft has offered a new feature called Core Parking in their latest Operating Systems which are Windows 7 and Windows Server 2008 R2. What Core Parking does is when many cores aren’t in use, operating system put the remaining cores to sleep. When these cores are necessary, the operating system wake the sleeping cores and allocate them to the additional work.

Modern microprocessors work with dynamic frequencies for each of their cores. Because the cores don’t work with a fixed frequency, it is difficult to predict the performance for a program. When the workload is becoming large, operating system changes the frequencies of its microprocessor's cores. The process of increasing the frequency for a core is known as overclocking.

But one main point is, the microprocessor cannot keep all the cores overclocked a lot of time, because it consumes more power and because of that its temperature increases faster. Then there have to be a proper cooling system to reduce the heat.

So that's the end of my first post in Parallel programming. Hoping to write another post with the next topic in Parallel programming.

Appreciate your feedback.

Happy Coding.

Regards,
Jaliya

Thursday, June 23, 2011

Word Automation Using C# and Visual Studio 2010

I have been engaged with Word Automation using C# for some time and I thought to share the basic steps of doing it. Word Automation is simply generating Word Documents programmatically. Lets take a simple scenario. Let's say that you have a common document which you want to address to different personals. And you are storing Person's details in an database. Since I want this example to be simple, I will assume that there will not be two Persons which have the same name which inheritingly means I can say the Person's name is unique.

So in my database I will have a Table called 'RECEIVER_DETAILS' which has following Fields.
  1. RECEIVER_TITLE
  2. RECEIVER_NAME
  3. ADDRESS_LINE1
  4. ADDRESS_LINE2
  5. ADDRESS_LINE3
  6. ADDRESS_LINE4
I have created a simple Windows Forms Application with a simple Windows Form like this.


Now what I want is when I typed the Name and press enter other fields should be automatically filled. Since this post is mainly about Word Automation I will not describe how to do that, and I think for you all it's a simple piece of work. Now what I want is when I clicked Generate button I want all address details to be written back in a Word Document. And that is a simle Word Automation. Since it's always better to use Step by Step approach, I will start from Step 01.

Step 01.

Open a Microsoft Word Document. I am using Microsoft Office 2010.


Now go to Insert tab, under that go to Quick Parts and under that click Field.


Then the following screen will appear.


From Categories drop down list select Mail Merge.


And from Mail Merge select MergeField, under Field Name type "To Title" and select "(none)" as Format.


Click OK and you will get something like this.


Likewise I have created some fields to store Person's address details.


Now you should save this document as a Word Template.


Now you have successfully created a Word Template and this template will be used to create new documents with Person's address details.

Step 02.

Now it's the programming part. I assume you all can write the part of code to fill text boxes, when you have typed the Name and hit Enter. Now open the solution which you have created the Windows Form in and add the following references to the Project.
  • Microsoft.Office.Tools.Word
  • Microsoft.Office.Interop.Word
In the Form code, add following lines to the using section.

using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Word;
using Microsoft.Office.Interop.Word;

Declare global type objects before Form Constructor.

Object oMissing = System.Reflection.Missing.Value;

// if you want your document to be saved as pdf
Object format = Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF;

Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();

In btnGenerate_Click event write the following.

// path of the Word Template document
Object oTemplatePath = @"C:\Users\Jaliya\Desktop\Temp\Word Automation.dotx";
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
int iFields = 0;

foreach (Word.Field myMergeField in oWordDoc.Fields)
{
     iFields++;
     Word.Range rngFieldCode = myMergeField.Code;
     String fieldText = rngFieldCode.Text;

     if (fieldText.StartsWith(" MERGEFIELD"))
     {
          Int32 endMerge = fieldText.IndexOf("\\");
          Int32 fieldNameLength = fieldText.Length - endMerge;
          String fieldName = fieldText.Substring(11, endMerge - 11);
          fieldName = fieldName.Trim();
          if (fieldName == "\"To Title\"")
          {
                myMergeField.Select();
                // check whether the control text is empty
                if (cboTitle.Text == "")
                {
                      oWord.Selection.TypeText(" ");
                }
                else
                {
                      oWord.Selection.TypeText(cboTitle.Text);
                }
          }
          if (fieldName == "\"To Name\"")
          {
                myMergeField.Select();
                // check whether the control text is empty
                if (txtName.Text == "")
                {
                      oWord.Selection.TypeText(" ");
                }
                else
                {
                      oWord.Selection.TypeText(txtName.Text);
                }
         }
         if (fieldName == "\"To Address Line 1\"")
         {
                myMergeField.Select();
                // check whether the control text is empty
                if (txtAddressLine1.Text == "")
                {
                      oWord.Selection.TypeText(" ");
                }
                else
                {
                      oWord.Selection.TypeText(txtAddressLine1.Text);
                }
         }
         if (fieldName == "\"To Address Line 2\"")
         {
                myMergeField.Select();
                // check whether the control text is empty
                if (txtAddressLine2.Text == "")
                {
                     oWord.Selection.TypeText(" ");
                }
                else
                {
                     oWord.Selection.TypeText(txtAddressLine2.Text);
                }
          }
          if (fieldName == "\"To Address Line 3\"")
          {
                myMergeField.Select();
                // check whether the control text is empty
                if (txtAddressLine3.Text == "")
                {
                     oWord.Selection.TypeText(" ");
                }
                else
                {
                     oWord.Selection.TypeText(txtAddressLine3.Text);
                }
          }
          if (fieldName == "\"To Address Line 4\"")
          {
                myMergeField.Select();
                // check whether the control text is empty
                if (txtAddressLine4.Text == "")
                {
                     oWord.Selection.TypeText(" ");
                }
                else
                {
                     oWord.Selection.TypeText(txtAddressLine4.Text);
                }
          }
     }
}

string s = @"C:\Users\Jaliya\Desktop\Temp";

// if you want your document to be saved as pdf
object savePath = s + "\\Temp Word.pdf";

oWordDoc.SaveAs(ref savePath, ref format, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);


// if you want your document to be saved as docx
object savePath = s + "\\Temp Word.docx";

oWordDoc.SaveAs(ref savePath, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

In the FormClosing event add the following code. If you are not using this part in the Form Closing event, after generating the document if you check Processes under Task Manager, you will see a Process called"WINWORD.EXE". To close that Process I am writing this tiny piece of code.

object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;
oWordDoc.Close(ref doNotSaveChanges, ref oMissing, ref oMissing);
oWord.Quit(ref doNotSaveChanges, ref oMissing, ref oMissing);


After clicking "Generate" button, here is the screen shot of what I got. I created a ".pdf" document.




And that's the basics of Word Automation Using C# and Visual Studio 2010. Feel free to ask any question and to give me your feedback.

Happy Coding.

Regards,
Jaliya

Sunday, June 19, 2011

Fatal Error : Failed object initialization when Installing AdventureWorks2008R2 Sample Databases

I recently installed AdventureWorks 2008R2 SR1 as a sample database in my SQL Server 2008 R2 to test SharePoint 2010 Enterprise Search with custom databases.While installing the AdventureWorks 2008R2 SR1 I faced some issues and I thought to share those issues and ways to solve those issues with you all.

First you can download AdventureWorks 2008R2 SR1 for free from the following link.
    Download  AdventureWorks 2008R2 SR1

After you have finished downloading, there will be a single self extracting zip file which contains all of the AdventureWorks sample databases for SQL Server 2008R2. When this zip file is run, all content is unzipped to a temporary directory and an installer application is automatically started. This application copies the database scripts and data files to the directory specified, and optionally installs sample databases. If some databases cannot be installed, a brief explanation is displayed and a link is provided for more information about how to resolve the installation issues.

This is what you will get when you ran the self extracting zip file.



Then I ticked that I accept the licence terms and clicked Next hoping that installation will go smoothly. Then the following Error appeared.


It says,

A fatal error occurred during installation. Details:

Failed object initialization (ISupportInitialize.EndInit).An exception occured in SMO while trying to manage a service. Error at object 'DatabaseSelection' in markup file 'DatabaseInstaller;component/databaseselection.xaml' Line 78 Position 3.


First I was little bit surprised. Then I started to troubleshoot the error. First what I did was check the Installation Guide for installing AdventureWorks 2008R2 SR1.

In that there were three main steps to follow. They were,
  1. Installing Full-Text Search.
  2. Enabling the SQL Full-text Filter Daemon Launcher Service.
  3. Enabling FILESTREAM,
I was pretty sure, I have enabled all features with Full-Text Search when I was installing SQL Server 2008 R2. But I wasn't sure about the other two. So after reading the Installation guide I went for Enabling the SQL Full-text Filter Daemon Launcher Service. And for that I needed to go to SQL Server Configuration Manager. I followed StartAll Programs, then Microsoft SQL Server 2008, then Configuration Tools, and then clicked on SQL Server Configuration Manager. And when I clicked on it I was astonished. I got another error.


It says,

Cannot connect to WMI provider. You do not have permission or the server is unreachable. Note that you can only manage SQL Server 2005 and later servers with SQL Server Configuration Manager. Invalid class [0x80041010]

Again I am pretty sure that I do have the permission and I am running on SQL Server 2008 R2. Then I Googled for this error and I found out the reason. Microsoft has provided you the full explanation of this error and answer in this link. After reading Microsoft's solution, in an elevated Command Prompt, I typed the following.

mofcomp.exe "C:\Program Files (x86)\Microsoft SQL Server\100\Shared\sqlmgmproviderxpsp2up.mof"

Then I navigated to SQL Server Configuration Manager and clicked on it. Now there was no error and successfully managed to open Configuration Manager. Now according to AdventureWorks 2008R2 SR1 Installation Guide, enabled the SQL Full-text Filter Daemon Launcher Service and fixed it's Start Mode to Automatic.

Then enabled the FILESTREAM by opening the SQL Server Management Studio (SSMS), and in the query window, running the below code,

EXEC sp_configure filestream_access_level, 1
RECONFIGURE

Now everything was good to go. Again I ran the self extracting zip file of AdventureWorks 2008R2 SR1. Finished extracting files and installer application automatically started. Again ticked that I accept the licence terms and clicked Next. Now there was no fatal error and AdventureWorks 2008R2 SR1 sample databases were ready for installation.

Hope someone gets needed help from this post. Appreciate your feedback.

Happy Coding.

Regards,
Jaliya

Tuesday, June 14, 2011

Business Connectivity Services in SharePoint 2010 Explained

Business Connectivity Services in SharePoint 2010 can be defined as the big brother of Business Data Catalog in SharePoint 2007. BCS is actually the upgraded version of Business Data Catalog in SharePoint 2007. The weaknesses of BDC in SharePoint 2007 are, BDC was mainly used to access the external data. Updating the extenal data was extremely difficult with BDC and what most people say is it is near to impossible.

But with BCS in SharePoint 2010, what Microsoft has does is it let you connect to any external data source which can be either external SQL Server, Windows Communication Foundation (WCF) Service or basically all other external data sources which supports Open Database Connectivity (ODBC) Service. What ODBC is, ODBC refers to a software API method to use with Database Management Systems. Main feature of ODBC is, it is independent of programming language and operational system and so it can be used to access different database systems. To connect to a other database, ODBC defines a connection. Connection is created to define a connection between a computer and a database stored on another system. The ODBC connection contains information needed to allow a computer user to access the information stored in a database that is not local to that computer.

The main key feature of BCS is, with SharePoint 2010 every SharePoint site can access and manipulate external data within SharePoint. When you retrieved data from external data source and the moment that you make changes to those data and update them, the changes will be reflected in the external data source.

Now I will describe the Business Connectivity Services Architecture in SharePoint 2010. Take a good look at the following image. I will explain what every component does in this architecture.


Things to Note

Please note that in SharePoint 2010, BDC refers to Business Data Connectivity and not Business Data Catalog in SharePoint 2007.

  • BDC Metadata Store
The BDC Metadata Store provides storage for a collection of external content types, each of which describes how to connect to the external store. The Metadata Store acts as part of the services layer. External content types are a fundamental building block of BCS.
  • BDC Runtime
The BDC Server Runtime understands how to reach into the back-end store and connect to data based on the external content types defined within the content type store. It’s important to note the new usage of the acronym BDC to refer to the set of services that provides connectivity that is a component of BCS.
  • Security
BCS provides integration with the Secure Store Service (SSS), as well as enabling your own security model. The Secure Store Service stores credentials in database(User Name and the Password) to authorize access to shared resources. SharePoint 2010 using the Secure Store Service to store and retrieve credentials to access external data sources.
  • Solution Packaging
Solutions built with BCS can be packaged as a Visual Studio Tools for Office (VSTO) package to be delivered to a rich client, including SharePoint Workspace, Outlook and Word. BCS also exposes APIs to extend solution packaging to target additional clients.
  • Out of Box UI
BCS carries forward the ability to display external data through a Web Part UI and provides deeper integration through the addition of external lists.
  • BDC Client Runtime
A symmetrical runtime is provided for client and server, enabling you to take solutions offline with a client-side cache and to connect and push changes back to the server in a consistent manner. Use of the BDC Client Runtime enables offline operations, interacting with the external data cache.
  • Design Tools
SharePoint Designer provides a wealth of out-of-box functionality for creating BCS solutions, including the ability to define external content types and external lists, and to define InfoPath forms to surface the data to create simple solutions. Visual Studio provides the ability for the professional developer to extend those capabilities to create advanced solutions while leveraging the existing framework. 
  • Cache
client-side cache provides the ability to sync changes to and from the client-side application with the external data source.

I hope you all got a some idea about how BCS in SharePoint 2010 works. Feel free to correct me if I am wrong with anything.

Appreciate your feedback.

Happy Coding.

Regards,
Jaliya

Monday, June 13, 2011

Everything about SPQuery Class

Every kind of Application or System no matter whether they are simple or complex, they needs their data to be stored in someplace. It can be either a Database, a XML file or simply a text file. And all those applications uses CRUD (Create,Read,Update,Delete) operations to maintain their data. So in SharePoint, one of the major way of Reading or Selecting data is using SPQuery Class in Microsoft.SharePoint Namespace.

Today I am going write about this SPQuery Class. The SPQuery Class is used to represent a query in the list view. Assuming you all know about SQL Select queries, to give you some basic idea on what SPQuery do is, It does what Select query in SQL does but syntaxes are totally different. Since I am hoping to write some examples using SPQuery, I think as we go along with this post you will definetely be able to identify the differences.

Then let's start. I will be using a custom list called Customer List. It contains following columns.
  1. Title - string
  2. Name - string
  3. Field1 - Number
  4. Field2 - Number
First of all, I will write a full simple example. Follwing code will retrieve all the items in the "Customer List" in which Name field equals to "Jaliya Udagedara".

using (SPSite oSPSite = new SPSite("http://ravanaserver/"))
{
     using (SPWeb oSPWeb = oSPSite.OpenWeb())
     {
           oSPWeb.AllowUnsafeUpdates = true;
           SPList oSPList = oSPWeb.Lists["Customer List"];

           SPQuery oSPQuery = new SPQuery();
           
           // your query writes here
           oSPQuery.Query = "<Where><Eq><FieldRef Name='Name'/><Value Type='Text'>Jaliya Udagedara</Value></Eq></Where>";
           SPListItemCollection oSPListItemCollection = oSPList.GetItems(oSPQuery);
           foreach (SPListItem item in oSPListItemCollection)
           {  
                // your code
           }
     }
}

Now I will write example for common scenarios. When modifying, modify only the part where I have put comment "// your query writes here".

  • Retrieve all Items.
    • For this you don't have to write any query. Just modify the above code as follows. This will return the all Items.
           SPQuery oSPQuery = new SPQuery();
           SPListItemCollection oSPListItemCollection = oSPList.GetItems(oSPQuery);

  • Retrieve items that a field matches a given value.
           oSPQuery.Query = "<Where><Eq><FieldRef Name='Name'/><Value Type='Text'>Jaliya Udagedara</Value></Eq></Where>";

  • AND Operator - Retrieve items that matches the following condition,
                                      (Field1 >= 500) AND (Field2 <= 1000)

           oSPQuery.Query = "<Where><And><Geq><FieldRef Name='Field1'/><Value Type='Number'>500</Value></Geq><Leq><FieldRef Name='Field2'/><Value Type='Number'>1000</Value></Leq></And></Where>";

  • OR Operator - Retrieve items that matches the following condition,
                                      (Field1 >= 500) OR (Field2 <= 1000)

           oSPQuery.Query = "<Where><Or><Geq><FieldRef Name='Field1'/><Value Type='Number'>500</Value></Geq><Leq><FieldRef Name='Field2'/><Value Type='Number'>1000</Value></Leq></Or></Where>";

  • BeginsWithANDContains
           oSPQuery.Query = "<Where><And><BeginsWith><FieldRef Name='Name'/><Value Type="Text">Jaliya</Value></BeginsWith><Contains><FieldRef Name="Name" /><Value Type="Text">Udagedara</Value></Contains></And></Where>";

  • IsNull - Retrieve all items Where Name field is empty,
           oSPQuery.Query = "<Where><IsNull><FieldRef Name='Name'></FieldRef></IsNull></Where>";

I think I wrote some examples for most common scenarios. Here is a table of Comparison Operators used in SPQuery Class.

Comparison Operators
General Meaning
Eq
=
Gt
> 
Lt
< 
Geq
>=
Leq
<=
Neq
<> 
Contains
Like
IsNull
Null
IsNotNull
NotNull
BeginsWith
Beginning with word
DateRangesOverlap
compare the dates in a recurring event with a specified DateTime value, to determine whether they overlap


Things to Note

But when writing these queries there is some thing that you all should note about. That is, if your field name contains any spaces for example like "First Name", in your FieldRef Name if you put as 'First Name', you will get a error like "No Matching Field". The reason behind this is when you are leaving spaces in field names, the actual field name changes. You can get the correct field name by opening the List in InfoPath designer and referring the name in that field. For 'First Name', you might get something like 'First_x0020_Name'.

Feel free to give me your feedback.

Happy Coding.

Regards,
Jaliya

Friday, June 10, 2011

How to create a SharePoint 2010 Polling Web Part easily

Today I am going write about how to create a simple and very user friendly SharePoint 2010 Polling web part. Since I am hoping to develop it as a fully customizable Polling web part, in here I am going to explain the concept behind it.

I had a requirement, which will allow SharePoint user's to vote for polls which are published by the SharePoint Administrator. You may think that we can use SharePoint Surveys which is already available in SharePoint 2010 as well as SharePoint 2007. But my thought of Surveys is, there are some limitations in Surveys and not to mention it has nice capabilities too.

If I talk about limitations, for an example I will mention one. Let's say that we want to create a Survey, which a user can vote once. And Survey has a nice optional inbuilt feature to block user from voting more than once. But again to one survey, we can add questions later. So let's take this scenario. Administrator adds a survey which has one question. He blocks user from voting twice. Someone votes and when he try to vote for the second time, SharePoint will not allow it. Then Administrator wants to add a another question to the created Survey. Then the problem arises. User can't answer to that question, because he is blocked from accessing the same Survey twice. So what will happen is, Administrator will have to take all the trouble of creating and configuring another Survey.

Since I did not want to get all the trouble, what I did was created a simple web part that will give the following functionalities.
  • Easy to add a new Poll with one question.
  • Can set a expiry date to the Poll and after it expires, users can't no longer see it or vote it.
  • Each user can't vote more than once.
  • Only the Administrator can view the results.
  • Results can be viewed as Bar Charts or Pie Charts.

Now I am going to explain how I created it. Concept is fairly simple.
  • First create two lists. One is to add Polls and the other is to store user's vote information.
  • Let's call the first list as "Poll List" and the other as "User Poll List".
  • Set "User Poll List" as a hidden list.
  • In "Poll List", create seven additional columns. Title is already there when you have created it. List columns are,
    • Title - string
    • Answers - Check Box, Set Check Box values as Yes,No,Pass. So Poll publisher can select which answers should be there in each question
    • Poll Created By - People Picker
    • Date Started - Date and Time
    • Date Expired - Date and Time
    • Total Yes - Number and this column is disabled
    • Total No - Number and this column is disabled
    • Total Pass - Number and this column is disabled
  • In "User Poll List", create one additional column. Again Title is already there. List columns are,
    • Title - string
    • Voter's Name - string
  • Now Open Visual Studio 2010 and create a Visual Web Part.
  • Put a some labels and set their text to empty and a Button. Let's name it as "Vote".
  • Put a Radio Button List, so later we can fill the answer to it.
  • Write method to get the last item in the "Poll List" which is not expired and call it in the Web Part Load event.
  • Fill labels and fill the radio button list from the received data of the last item.
  • Now in "Vote" Button click event we are going to insert user selected data to both lists.
    • First query the "User Poll List" and check whether there is a item which the 'Title' is the current question and the 'Voter's Name' is the current logged on user's name. If there is, that means current logged on user has already voted for the selected question.
    • If there is no item, that means he/she has not voted for this question yet. So first add a item to the "User Poll List" and then update (increase the value by 1) the 'Total Yes'/'Total No'/'Total Pass' field in the "Poll List" to the relevant question.
  • And that's all. Now you might think that there will be a heavy load in the "User Poll List" as user's votes.
  • For that when a question has expires, we will delete all relevant items in the "User Poll List". By doing that we can avoid getting "User Poll List" by overloading.
I have created a nice Polling Web Part using above steps. If you see any drawbacks of the above method, please feel free to post a comment and appreciating your feedback.

Happy Coding.

Regards,
Jaliya


Update - 06th December 2011

Hello guys, since a lot of people are asking for the source code of my Polling Web Part, I have uploaded the source. You can download it from here. Please note that, I have not uploaded the full source code. But I am pretty sure, you will find the provided source code interesting.

Happy Coding.

Regards,
Jaliya

Saturday, June 4, 2011

Watch For Process Start using C#

I wanted to write a console application, that will watch the system and trigger an event when a new process has started. So did some coding using ManagementEventWatcher Class which comes under System.Management namespace.

I am going to post down the code, but since this can be used to do unethical things like creating a simple virus, I will only write down the two most important methods.

// this method will capture every process start
public static void MonitorForProcessToStart()
{
      // create event query to be notified within 1 second of a change in a service
     WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1),
          "TargetInstance isa \"Win32_Process\"");

      ManagementEventWatcher watcher = new ManagementEventWatcher();
      watcher.Query = query;
      watcher.EventArrived += new EventArrivedEventHandler(ProcessStartEvent);
      watcher.Start();
}

In Here TimeSpan is a timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested, and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered.

// when a new process has started, it will trigger this event
public static void ProcessStartEvent(object sender, EventArrivedEventArgs e)
{
      // when this method has triggered a new process has started.
      // in here you can do what ever you want.
}

Using these two methods, there is a lot a good programmer can do. Not to mention you can do unethical things too. So I will not go deeper about the things you can do.

Feel free to give me your feedback.

Happy Coding.

Regards,
Jaliya

Friday, June 3, 2011

Debugging SharePoint Sandbox Solutions - Process 'SPUCWorkerProcess.exe' is not running?

When you have created for an example SharePoint 2010 Event Receiver as a Sandbox solution using Visual Studio 2010 and when you are going to debug your project, sometimes you might get this error "Process 'SPUCWorkerProcess.exe' is not running."

The reason behind this error is, if you are using SharePoint 2010 on a Domain Controller then by default Sandbox solutions are disabled on it. So if you're running SharePoint 2010 on a DC you will need to add a ACL Access Rule to enable Sandbox Solutions. ACL(Access Control List ) means with respect to a computer file system, a list of permissions attached to an object. So without this Access Rule the Microsoft SharePoint Foundation User Code Service will start but the SPUCWorkerProcess.exe won't. Because by default it is disabled. To enable it, you will need to run the following PowerShell script. Make sure to run PowerShell as Administrator.

$acl = Get-Acl HKLM:\System\CurrentControlSet\Control\ComputerName 
$person = [System.Security.Principal.NTAccount]"Users" 
$access = [System.Security.AccessControl.RegistryRights]::FullControl 
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit" 
$propagation = [System.Security.AccessControl.PropagationFlags]::None 
$type = [System.Security.AccessControl.AccessControlType]::Allow 
$rule = New-Object System.Security.AccessControl.RegistryAccessRule($person, $access, $inheritance, $propagation, $type) 
$acl.AddAccessRule($rule) 
Set-Acl HKLM:\System\CurrentControlSet\Control\ComputerName $acl

Happy Coding.

Regards,
Jaliya