Friday, December 28, 2007

My first SharePoint webpart

A few months ago I created my first SharePoint webpart.
The conceptual idea was to have a webpart where items from the contenttype calendar would be aggregated and displayed to the enduser in the form of an eventlist.
Something like:
EvenementenWebPart01
When the users clicks on an item, a new page would be displayed with more information about the selected event.
Something like:
EvenementenWebPart02

1st step in creating this WebPart was to find out what components are involved.
So the WebPart will do the following basic steps every time it is viewed.
1. Get all the listitems (based on a public property's "SiteName" and "ListName" )
2. Sort the listitems
3. Cut the list to the appropriate size (based on a public property "NumberOfEvents")
4. Transform the list to an appropriate XML representation
5. Transform the XML representation by using a XLS (based on a public property "XSL")
6. Additionally if an event happens in the future, add a link to an InfoPath form where the user can subscribe to the upcoming event. This form will be forwarded by email.

Next time I will post some short pieces of code.
For now I just send you to this great resource on how to build your own WebPart for SharePoint

Thursday, December 27, 2007

Regular expression? No Wiener Melange for me please....

This is what most of us will say when we hear the term "Regular expression". No it's not a brand new coffee brand, no it isn't the most common used (and therefore regular) facial expression of the world. No this time I'm talking about some sort of query language used by freaky developers. Recently my program experience is expanding (fast or slow, it IS expanding) and from time to time I literally bounce of a new subject.
Regular expressions is just one of them.
The concept really is fascinating!
These expressions can do almost anything, except make you a delicious Wiener Melange (on the other hand, could your coffee machine make one for you "without" regular expressions? that the question!).
Well jokes aside, I really was fascinated by the concept and couldn't resist taking a little sneak preview in this crazy world of expressions.
An there come's the "bounce"...
Really, can anyone tell me what the hack this means???
^((?>[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-
\x7f])[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!
\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+)+|"((?=[\x01-
\x7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?
<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|
[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-
\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$

Well, if you break it down piece by piece you will eventually see some logic in the above syntax. To safe you all some backtracking time, here is the answer: The above syntax can be used for validating the syntax of an email address. Well, for me this isn't that logical. From a conceptual point of view these sort of expression can have tremendous power and can be used in very complex situations like pattern recognition. For now I say: Back to the schoolbooks, we've got a lot to learn!

AltirisSVS Class

It's been a while since my last post and progress on my first little side-project is.... slow... The more I think of this project, the more I realize that I'm sort of reinventing the wheel. There are some great free alternative ways of doing what i want and i will look into them as soon as possible. So for now, 
* 1st project status: on-hold

As many of you programmers over the world would recognize, There's ALWAYS plenty of room for new ideas in a programmers head, but way to little free time to actually program those wonderful ideas. One of those ideas I challenged before is the idea of creating a general .NET class that will provide me with various methods for the purpose of controlling the SUPER COOL program AltirisSVS (Software Virtualization).

A little time ago I created a little solution but as messy as i am i don't know where I have the sourcecode of this little thingy. Didn't have a backup, so I'm forced to recreate the whole program, this time I will code my thing in C# (as apposed to the previous version that was created in VB.NET).
To give you a short overview of what the hell I'm going to do we will dive in a little deeper in the magical world of virtualization.

So what is AlririsSVS?
The guys at Altiris created a program that well... virtualizes software installations. To give you a more understandable image, imagine yourself having a pc. That's probably not that hard to imagine, since most of you reading this post are doing this on there own personal desktop. Next step is look at your word processor. Most likely you will find a program like Microsoft Word 2003 or something similar like it. Nothing crazy going on at this stage. Until your boss sends you an MS Word document that was created with the newer version of Microsoft Office 2007 (XDOC format). This is a document format that isn't supported by your older 2003 version of Office. Still not that big of a problem, just upgrade your Office version to the newer 2007 version and off we go! But maybe you just liked office 2003 or corporate policies prohibits you to delete this version. Now what to do???

Here is when AltirisSVS come's into play!!!
Most program's on your pc don't "bite" each other, but some programs will! Program's like Microsoft Office are using so called shared dll files. These files are transferred to your computer during installation and will nestle themselves wherever they are comfortable. Nothing wrong with this, those little dll's will do there work just fine and you probable will never notice them, until you want to run 2 different version of the same program next to another on one pc. Then the new installation will probably overwrite some of these shared dll files without notifying other programs on your pc.

Now you can find yourself with a computer who was 2 versions installed of the same program (for example MS Word 2003 / MS Word 2007). The shared files on your computer will all be version 2007 and you will have trouble running the older 2003 version.
So this is a big NO GO!!!
This problem doesn't occur if you virtualize these installations and run them in separated virtualized environments. Well, lets install VMware or Virtual PC, and install the software into a new virtual pc most of the people will think, but there are WRONG! Install AltirisSVS and you will be able to create the so called "Layers"
In this layer you can then install an application. The layer will be an "sandboxed" environment where all the program files and shared dll will be found. This layer is very flexible, you can enable/disable it, making it possible to totally hide you installed application from the operating systems perspective. You can download a free version from the website (need to be a registered user, so first register on there website). Just play with the software for a while and you will see!

Question some people might ask, if this software is that great, why wanna code something around it? Well, at Altiris they did a great job building the whole virtualisation platform, and on top of that, they created a nice WMI interface so that you can manage your layers through code. And, where there are interfaces, there are those annoying programmers who just can't resist to talk to it.
Well, that's the main reason i started this project.
Why? because i can!
So the first thing to do is making a little framework as a base, letting me extend this framework in the future.

  • Create a little WMI Wrapper for the Altiris WMI class
  • Create a C# Class
    • Activate_Layer(string LayerName)
    • DeActivate_Layer(string LayerName)
    • EnumerateLayers()

Additional resources:
Microsoft WMI Code Creator
Good article on how to make a SVS wmi script
Tech MOSS team, created some nice tools for developers

A little sample code preview (written by rcboenne)

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using System.Management;

    5 using System.Windows.Forms;

    6 

    7 namespace Focus_XP_SVS_Layer_Console

    8 {

    9     public class WMITest

   10     {

   11         public static void Test()

   12         {

   13             try

   14             {

   15 

   16                 ManagementScope scope = new ManagementScope("root\\default");

   17                 scope.Connect();

   18                 ManagementClass classInstance = new ManagementClass(

   19                 scope,

   20                 new ManagementPath("AltirisVSProv"),

   21                 null);

   22 

   23                 // Obtain in-parameters for the method

   24                 ManagementBaseObject inParams =

   25                 classInstance.GetMethodParameters("EnumerateLayers");

   26 

   27                 // Add the input parameters.

   28                 inParams["Verbose"] = 1;

   29 

   30                 // Execute the method and obtain the return values.

   31                 ManagementBaseObject outParams =

   32                 classInstance.InvokeMethod("EnumerateLayers", inParams, null);

   33 

   34                 // List outParams

   35                 Console.WriteLine("Out parameters:");

   36                 Console.WriteLine("EnumData: " + outParams["EnumData"]);

   37                 Console.WriteLine("ReturnValue: " + outParams["ReturnValue"]);

   38             }

   39             catch (ManagementException err)

   40             {

   41                 MessageBox.Show("An error occurred while trying to execute the WMI method: " + err.Message);

   42             }

   43         }

   44 

   45     }

   46 }




Friday, December 7, 2007

Fighting against my own ignorance

Yesterday I started, what seemed like, a little side project. The idea was very straightforward, just write a little GUI to control some installation scripts. Soon after finishing the brainstorm session I eagerly started to code the little thingy.

  • First thing I wanted in place was a little decompression class for the purpose of decompressing a cabinet file. After searching a way to do this from within the code I came across several problems so I thought, what the hack, let’s just make a call from within our code to the external windows program Expand.exe and save some time instead of trying to reinvent the wheel. This eventually did the trick for me! 1 down, a little more to go ;-)


       29         private void StartProcces(string FileName, string Arguments, TextBox OutputTextBox)

       30         {

       31             System.Diagnostics.Process extractCmd = new System.Diagnostics.Process();

       32             extractCmd.EnableRaisingEvents = true;

       33             extractCmd.StartInfo.FileName = FileName;

       34             extractCmd.StartInfo.Arguments = Arguments;

       35             extractCmd.StartInfo.RedirectStandardOutput = true;

       36             extractCmd.StartInfo.RedirectStandardInput = true;

       37             extractCmd.StartInfo.UseShellExecute = false;

       38             extractCmd.StartInfo.CreateNoWindow = true;

       39             extractCmd.Start();

       40             if (OutputTextBox != null)

       41             {

       42                 string StringToWrite = null;

       43                 while (null != (StringToWrite = extractCmd.StandardOutput.ReadLine()))

       44                 {

       45                     AddToProccesViewer(StringToWrite, OutputTextBox);

       46                 }

       47             }

       48             extractCmd.WaitForExit();

       49         }





  • 2nd part of this little adventure was the creation of a class that made it possible to actually run external program’s and that give me the option to redirect it’s output to something like a textbox for instance. The main part of this code I already created for the extraction of the cabinet file. At first a had a little problem writing the output real-time, but after some little tweak’s I had it, a working class to run some simple dos programs.
  • 3rd part would be the easiest of them all, just read the little XML file into the program and iterate through the imported document letting me run the scripted programs. Well, this sounds simpler than it truly is (taking into consideration that the whole XML stuff is quite new to me). First I started off importing the whole XML into a dataset, this didn’t work that well for me. ok, let’s thinks, the problem I had was that I was missing some sort of relation between the imported items. Maybe XSD could help me out of this mess after playing a little with the program XSD.exe I suddenly a whole class that was created from my little XML file. A little overkill if you ask me. So I started it all over. The trick I now use is that I added a little attribute to the program elements called id. Now I’m using only the xml file (no extra schema’s) and iterating thru the file using several XPath expressions instead of relying of the internal relationship of the document, so for now, no usage of the crazy ChildElements.


       79         private void ReadXml()

       80         {

       81             if (System.IO.File.Exists(TMP_PATH + XML_FILENAME))

       82             {

       83                 string myXMLfile = @"" + TMP_PATH + XML_FILENAME;

       84                 string myXMLschema = @"" + TMP_PATH + XSD_FILENAME;

       85                 doc = new System.Xml.XmlDocument();

       86                 doc.Load(TMP_PATH + XML_FILENAME);

       87                 foreach (System.Xml.XmlNode n in doc.SelectNodes("//Program[@id]"))

       88                 {

       89                     AddToProccesViewer("Title: " + n.SelectSingleNode("Title").InnerText, textBox1);

       90                     AddToProccesViewer("Command: " + n.SelectSingleNode("Command").InnerText, textBox1);

       91                     AddToProccesViewer(BuildParameter(n.SelectSingleNode(".").Attributes[0].InnerText), textBox1);

       92 

       93                     string cmd = n.SelectSingleNode("Command").InnerText;

       94                     string param = BuildParameter(n.SelectSingleNode(".").Attributes[0].InnerText);

       95                     string showoutput = n.SelectSingleNode("ShowOutputInWindow").InnerText;

       96                     if (showoutput == "True")

       97                     {

       98                         StartProcces(cmd, param, textBox1);

       99                     }

      100                     else

      101                     {

      102                         StartProcces(cmd, param, null);

      103                     }

      104                 }

      105             }

      106         }






  • 4th part of the project would be putting the whole thing together. This is the currently state of the project. I discovered a little inconvenience, Dos program’s that require user input seem to “hang”, so I have to trigger some sort of event in case this happens and let the user (or the Deploy.xml scripting file) choose the appropriate action. After having resolved this issue I will take on another challenge. I have to build some sort of functionality that makes it possible to editing file’s that are extracted from the cab file based on some sort of user input (Example: The installation program asks a destination directory and has to change several batchfile’s in the cab file to make the necessary changes that will make the batchfile’s copy file’s to this user provided path)

That’s it for now, back to code!

Wednesday, December 5, 2007

Welcome.♦

My first post will be about a little program I'm going to create.
The purpose of this program is to make a very extensible setup program.
Recently i finished a project where a SharePoint website was delivered to a customer. The installation procedure was already greatly simplified by my colleague's and the only thing the customer would have to do is simply adjust a little batchfile and a xml file and run the batch file.
The problem with this sort of deployment of an application is that it's mainly functional and has a lack of GUI.
So after a little brainstorming the idea was born to create an flexible/extensible installer method which can be used for new projects.
The problem with MSI is that is rather complicated to build (if you don't know what you’re doing)
So without any further ado i present to you the concept of the idea:

First of all is that the whole setup package will consist of only 2 files.

  • Setup.exe
  • Deploy.cab
The setup.exe will automatically decompress the 2nd file and in there it will find an xml file called "Deploy.xml"
This "Deploy.xml" will hold all the necessary actions setup.exe will perform and will look something like:

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

    2 <Deploy>

    3     <LogoImage>.\Logo.bmp</LogoImage>

    4     <ShowOutputWindow>True</ShowOutputWindow>

    5     <GenerateLogFile>True</GenerateLogFile>

    6     <LogFileName>Result.log</LogFileName>

    7     <Program id="1">

    8         <Title>Ping localhost...</Title>

    9         <Command>ping</Command>

   10         <Parameters>

   11             <Parameter>localhost</Parameter>

   12         </Parameters>

   13         <IsConsoleApp>True</IsConsoleApp>

   14         <ShowOutputInWindow>False</ShowOutputInWindow>

   15         <GeneratesOutputErrorCode>True</GeneratesOutputErrorCode>

   16         <IsShowStopper>True</IsShowStopper>

   17     </Program>

   18     <Program id="2">

   19         <Title>Copy *.log</Title>

   20         <Command>XCopy</Command>

   21         <Parameters>

   22             <Parameter>*.*</Parameter>

   23             <Parameter>d:\</Parameter>

   24         </Parameters>

   25         <IsConsoleApp>True</IsConsoleApp>

   26         <ShowOutputInWindow>True</ShowOutputInWindow>

   27         <GeneratesOutputErrorCode>True</GeneratesOutputErrorCode>

   28         <IsShowStopper>True</IsShowStopper>

   29     </Program>

   30 </Deploy>