Archives

Archives / 2009
  • WPK – 2: Some thoughts, and my first really small databound app

    My second article on using WPF from PowerShell. You can download WPK as part of the Windows 7 Resource Kit PowerShell Pack. When you can navigate to the folder <My Documents>\WindowsPowerShell\Modules you see the modules that are installed. The folder WPK contains the WPK module.

    On the Modules level a few documents are installed:

    • Readme1st.txt – information on installing, using, uninstalling the PowerShellPack
    • About the Windows 7 Resource Kit PowerShell Pack.docx – an overview of the available modules
    • Writing User Interfaces with WPK.docx - the first place to get started when working with WPK

    Especially the Readme1st.txt contains two interesting pieces of information:

    1. The file starts with the following text:

      Readme for the Windows 7 Resource Kit PowerShell Pack

                               by James Brundage

                   Copyright (c) 2009 by Microsoft Corporation
                    Portions copyright (c) 2009 James Brundage
                               All Rights Reserved


      I thought James Brundage is an employee of Microsoft, why does he own portions of the copyright?

    2. The disclaimer contains the following text:

      The Windows 7 Resource Kit PowerShell Pack included on the companion CD is
      unsupported by Microsoft and is provided to you as-is, with no warranty or
      guarantee concerning its functionality. For the latest news and usage tips
      concerning this PowerShell Pack, see the Windows PowerShell Team Blog at
      http://blogs.msdn.com/powershell/.

      So no support from Microsoft’s side. I wonder how issues will be resolved and new releases will be published.

    Ok, and now on to some programming. In the document Writing User Interfaces with WPK.docx we find a nice example of a process viewer that updates the list of processes every 15 seconds.

    A simple process viewer
    1. New-ListView -Width 350 -Height 350 -DataBinding @{
    2.    ItemsSource = New-Binding -IsAsync -UpdateSourceTrigger PropertyChanged -Path Output
    3. } -View {
    4.    New-GridView -AllowsColumnReorder -Columns {
    5.        New-GridViewColumn "Name"
    6.        New-GridViewColumn "Id"
    7.    }
    8. } -DataContext {
    9.    Get-PowerShellDataSource -Script {
    10.        Get-Process | ForEach-Object { $_ ; Start-Sleep -Milliseconds 25 }
    11.    }
    12. } -On_Loaded {
    13.    Register-PowerShellCommand -Run -In "0:0:15" -ScriptBlock {
    14.        $window.Content.DataContext.Script = $window.Content.DataContext.Script
    15.    }
    16. } -asjob

    See the document for a great explanation on how it works.

    When looking at this example I had a few questions:

    1. What if I don’t want to do a timed update, but just bind to some existing data?
    2. All examples do the data collection in the Get-PowerShellDataSource script block, is it possible to have the data already somewhere in a variable?
    3. Can I skip the binding stuff, I know its really powerful, but I want to start simple?
    4. Retrieve data in a background job is really cool, but what if we just want to load data and go?

    My first simple try after a lot of testing and tweaking is the following:

     

    Some names and ages
    1. New-ListView -Show -DataBinding @{
    2.    ItemsSource = New-Binding -Path Output
    3. } -View {
    4.    New-GridView -Columns {
    5.        New-GridViewColumn "Name"
    6.        New-GridViewColumn "Age"
    7.        }
    8. } -DataContext {
    9.    Get-PowerShellDataSource -Script {
    10.        $list = @()
    11.        $list += New-Object Object |
    12.            Add-Member NoteProperty Name "Serge" -passthru |
    13.            Add-member NoteProperty Age "43" -passthru
    14.        $list += New-Object Object |
    15.            Add-Member NoteProperty Name "Dinah" -passthru |
    16.            Add-member NoteProperty Age "42" -passthru
    17.        $list += New-Object Object |
    18.            Add-Member NoteProperty Name "Scott" -passthru |
    19.            Add-member NoteProperty Age "8" -passthru
    20.        $list += New-Object Object |
    21.            Add-Member NoteProperty Name "Dean" -passthru |
    22.            Add-member NoteProperty Age "4" -passthru
    23.        $list += New-Object Object |
    24.            Add-Member NoteProperty Name "Tahne" -passthru |
    25.            Add-member NoteProperty Age "1" -passthru
    26.        $list
    27.    }
    28. }

     

    I still use binding to the output, and in the datacontext script block I write the elements to bind to to the output. I still don’t bind to pre-calculated data in a variable.

    After a lot more testing I came to the following code:

    Names and ages from variable
    1. $list = @()
    2. $list += New-Object Object |
    3.    Add-Member NoteProperty Name "Serge" -passthru |
    4.    Add-member NoteProperty Age "43" -passthru
    5. $list += New-Object Object |
    6.    Add-Member NoteProperty Name "Dinah" -passthru |
    7.    Add-member NoteProperty Age "42" -passthru
    8. $list += New-Object Object |
    9.    Add-Member NoteProperty Name "Scott" -passthru |
    10.    Add-member NoteProperty Age "8" -passthru
    11. $list += New-Object Object |
    12.    Add-Member NoteProperty Name "Dean" -passthru |
    13.    Add-member NoteProperty Age "4" -passthru
    14. $list += New-Object Object |
    15.    Add-Member NoteProperty Name "Tahne" -passthru |
    16.    Add-member NoteProperty Age "1" -passthru
    17.  
    18. New-ListView -Name mylistview -Show -View {
    19.    New-GridView -Columns {
    20.        New-GridViewColumn "Name"
    21.        New-GridViewColumn "Age"
    22.    }
    23. } -On_Loaded {
    24.    $mylistview = $window | Get-ChildControl mylistview
    25.    $mylistview.ItemsSource = $list
    26. }

     

    In the above code I create a variable with a list of objects with two properties, Name and Age, and bind the ItemsSource property of the ListView to this variable.

    I bind the data in the Loaded event, the complete control tree is in place when this event fires.

    I have named the ListView control ‘mylistview’, and with the  code in line 24 I can find the control by name. The $window variable points to the implicitly created Window control surrounding the ListView, and is always available.

    Note that if we add the –AsJob parameter to the New-ListView command, the creation and binding is done in a background job on another thread, and the $list variable is not visible, not even if it is defined as a global variable (as $global:list)

    Diving into this simplification kept me busy for a while and gave me as a WPF nono some insights in how things are working in WPF when doing this from PowerShell.

    One question I still have in this simple example: is there an easier way to fill the $list variable so its still useful for databinding.I tried $list = @{ Name="Serge"; Age="43" }, @{ Name="Dinah"; Age="42" } but that does not work:-(

    Let me know if this is of any help to you.

    Happy coding!

  • WPK - 1: Creating WPF applications using PowerShell

    My first article on using WPF from PowerShell. What is WPK? Were can you get it? How to get started?

    I have been programming in PowerShell since 2006. At Macaw we use PowerShell for most of the development on the Macaw Solutions Factory. I have written thousands and thousands of lines of code in PowerShell 1.0. Some of the GUI tools in the Macaw Solutions Factory are even written completely in PowerShell. We use PrimalForms for the generation of the PowerShell code to render the GUI.

    PrimalForms: PrimalForms Community Edition is a free GUI builder tool for PowerShell users. It edits and stores Windows Forms in a native XML format and generates PowerShell code on demand. Sample forms included.

    More complex GUI tools are written in standard C#/WinForms. I prefer to have the tools in the Macaw Solutions Factory to be written completely in PowerShell. The reason is that most innovations to the Macaw Solutions Factory are done in real world projects. Because the Macaw Solutions Factory almost completely consists of script code, it is possible to add new features on any development machine that checked out the Factory code together with the source code of the project. No special development environment is needed. Good innovations are merged into the trunk of the Factory. Also fixing issues or making project specific modifications is a breeze.

    Writing WinForms applications using PowerShell never really worked well for us. Writing WinForms applications without designer is just terrible. PrimalForms makes life better, but still…

    Enter WPF! I have been playing with WPF and PowerShell a few years ago. Problem was that PowerShell had to be executed in a Single Threaded Apartment (STA) instead of the default Multi Threaded Apartment (MTA). My first discussion on this with Bruce Payette never resulted into a good working solution.

    A few days ago I ran across an interesting project at CodePlex: PowerBoots. This tooling provides WPF from both PowerShell 1.0 and PowerShell 2.0. I did some tests with it, and had some trouble, partly due to complete lack of knowledge of WPF. While searching the web I also stumbled upon WPK, the Windows Presentation Foundation PowerShell Kit. It is part of the just released Windows 7 Resource Kit PowerShell Pack (most things work on any OS with PowerShell 2.0 installed). WPK takes a very similar approach as PowerBoots. Check them both out!

    It is Christmas time. This means: two weeks no real company work, a bit of free time to dive into something new. I have been running around the last three days in PowerBoots and WPK, and I must say: the demo’s look great and most of them work, but even the most simple baby steps completely fail on me, especially due to my complete ignorance of what happened in the WPF space for the last years. Yes, I am ashamed of myself. Time to catch up… baby steps at a time. There are actually two things to dive into: the new features of PowerShell 2.0 and WPK. So don’t expect much of the next posts, it is all really basic stuff, but I see on my blog that the baby step posts are the most popular posts. Posts like how to call a PowerShell function with arguments (fn –arg1 a –arg2 b instead of fn(a,b)). So expect some post at this level… is just write down the things I go through myself.

    To get yourself started on the possibilities of WPK, have a look at the WPK video’s available on Channel 9. James Brundage, part of the Microsoft PowerShell Test team, does a good job on explaining WPK. There are a few videos there now, with more to come. For questions have a look at the discussion thread on the PowerShellPack site.

    Happy WPK’ing..

  • Fun: Quoted on SharePoint 2010 Development with Visual Studio in InfoWorld Article

    When I was at the SharePoint Conference 2009 in Vegas I was sitting in the hallway working on my little white Mac Book writing a blog post on SharePoint 2010 when a guy passed by. “Can I ask you some questions?” “Sure”, I said. “If I did anything with SharePoint?” he asked me… Ok, sitting with a Mac on a Microsoft conference can be strange, but hey: VMware Fusion did let me run the Technical Preview of SharePoint 2010 on my little Mac Book with 4GB, which couldn’t be said of my Dell running Windows XP at the time, not supporting 64 bits virtualization with Microsoft tools. We talked for a few minutes, he made some audio recordings, and off he was.

    It resulted in a nice article in InfoWorld with some quotes by “van den Oever”. Never knew I said such smart things;-)

    Read it at http://www.infoworld.com/d/developer-world/why-developers-sharepoint-2010-224

    And…. when you want the just release public beta of SharePoint 2010, download it:

    HERE!

    This link is provided by Microsoft The Netherlands to a group of people called the “Wave 14” ambassadors. We have a small competition between the ambassadors: the one who gets the most clicks gets an XBox!! So help me out, click it… often! And I will make sure that I blog a lot about SharePoint 2010!

  • The bear goes loose: Office 2010 public beta link (includes SharePoint 2010!)

    An old Dutch phrase… translated into bad English! But it is going to happen: the first public beta of the Office tools… including: SharePoint 2010!

    And where can you download it… I know it… download it

    HERE!

    This link is provided by Microsoft The Netherlands to a group of people called the “Wave 14” ambassadors. We have a small competition between the ambassadors: the one who gets the most clicks gets an XBox!! So help me out, click it… often! And I will make sure that I blog a lot about SharePoint 2010!

  • SharePoint 2010: #SPC09 - SSP is dead, long live Service Applications!

    Notes from the SharePoint Conference 2009 session "Introduction to Service Applications and Topology". This is my personal interpretation of what has been said during the presentation. Don't shoot me if I interpreted something wrong:-)

    In SharePoint 2010 Shared Service Providers (SSP's) are replaced by Service Applications. Services are no longer combined into a SSP. Services are running independent as a service application.

    So in MOSS 2007:
    SSP: combines services like Search, Excel Services, User Profiles, ... into a shared service provider.

    In SharePoint 2010:
    Service Applications: services like Search, Managed Meta Data, .., your service (20 services in SharePoint Server) are running "unboxed" and independent.

    So SharePoint 2010 provides a la carte unboxed services. You can configure which services are running on an application server. Per web application you can configure which services are consumed.

    When migrating MOSS 2007 to SharePoint 2010 SSPs will upgrade into Service Applications.

    SharePoint Foundation 2010 (WSS 4.0) provides the SharePoint Service Application Framework.
    New products like Office Web Apps, Project Server, Gemini (PowerPivot) use this application framework, and this platform can also be used by third parties or you to create custom services.
    You can plug your management UI for your service into the Service Management page.

    A web application does not communicate directly to a service application, but does this through a proxy:
    Web Application <-> Service Application Proxy <-> Service Application

    So a general workflow can be:
    Browser -> Web Front End ->(Request) Application Server ->(Result) Web Front End -> Browser

    SharePoint 2010 does contain a fault tolerant round-robin software load balancer with support for hardware load balancing, so it is possible to have multiple application servers.

    The Service Application infrastructure provides application isolation: each service application can use separate databases if needed and optionally run in separate app pool. There is support for multiple service apps for a service with different accounts and databases ==> Great for multi-tenancy (hosting for multiple customers on same platform)

    Services are flexible, secure and provide cross-farm federation:

    • Trust based security between farms, claims based authorization within the farm
    • Share to anyone, consume from anywhere
    • WCF based web services for communication
    • No direct DB Access
    For example: Taxonomy, has cross farm federation. Probably same for content types?

    Administration:

    You can manage which services are running on a server.
    In Central Administration UI: list of services, indented under a service you see the proxy.

    Through the wizards you get database names with guids at the end. Better to create manually form Central Administration, or create services through PowerShell.

    Per web application you can configure which services apps you want to be available. By default all web applications use all service applications available. You can change this into a custom configuration. Use the Manage Service Associations page for this.

    Service applications can be published to make them available outside the current farm. It allows you to select the connection type, for example https or net.tcp. Note that there must be a trust relationship with the farm that wants to consume your service. The service is published on a url. Through this url an other farm can find the published services. Url is in the following format: https://myfarm/Topology/topology.svc

    The other farm can connect to your farm through a remote service connection.

    Although manual adminstration and configuration of SharePoint 2010 can be done through Central Admin, the future of SharePoint administration is PowerShell.

    With respect to Services:

    Get-SPServiceApplication
    returns the set of service applications.
    Do Get-SPServiceApplication-name yourservice to get the service object. Do Get-SPServiceApplication -name yourservice | fl to see all properties of the service object.

    There are almost a hundred Cmdlets to manage your services.

    Side note: It now really becomes time that all administrators learn PowerShell. In my company (Macaw) we use PowerShell extensively for our Macaw Solutions Factory. Everything from configuration, build and deploy through DTAP is done with PowerShell.

    It is possible to delegate management of a particular service to someone, that person then has only access to that the management UI in Central Administration for that particular service.

    Access security: specified claims principals have access to a service application. By default the "farm claim" has access, but this can be removed ad more detailed claims can be configured for more granular access rights, or example read versus read-write.

    Service applications can spawn their own timer jobs.

    Generally ISV's will build service applications on the SharePoint Service Application Framework, but for large organizations it could be interesting for SI's to create services to specialized functionality and farm-to-farm fedaration .

    For repeatable configuration over your DTAP configuration, use PowerShell to create and manage the services.

    You can create complex farm configurations where farms can share service applications. For example: two farms can share the user profile service.

  • SharePoint 2010: Client side JavaScript Object Model Library written in Script#?

    Note: this blog post is based on experiences with the SharePoint 2010 Technical Preview version.

    SharePoint 2010 now extends the object model to the client. A remote object model proxy is available for C# development (including Silverlight) and a Javascript client library which can be found at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\SP.js, accessible at /_layouts/SP.js.

    I tried to understand what happens in the Javascript code, did some document formatting on it to get it readable. But not really a Javascript wizard myself I didn't really got the hang on it. But when I scrolled to the end of the SP.js file I found the following lines:

    // ---- Do not remove this footer ----
    // Generated using Script# v0.5.0.0 (http://projects.nikhilk.net)
    // -----------------------------------

    Now I understand why some of the code is not that readable: it is generated code. Script# is used for creating the client side object model API!

    Have a look at http://projects.nikhilk.net/ScriptSharp for more info on Script#.

    I never dared to use Script# i a real project going into production, especially because the last version came out in August 2008. But Microsoft does not seem to have a problem with it. The Microsoft team is even running an older version that available for download (version 0.5.1.0).

    As far as I know the Office Web Applications (online Word, Access and PowerPoint) are written with Script# as well. See http://www.nikhilk.net/ScriptSharp-Large-Projects.aspx. So maybe it is time now to really dive into Script#! Anyone dare to it for production code in their projects already? 

    Disclaimer: All information in this blog post is based on my personal interpretation of information collected at the SharePoint Conference 2009 and experiences with SharePoint 2010 Technical Preview version provided to my company in the PEP program.


  • SharePoint 2010: Site exporting as WSP solution (Part 1)

    Note: this blog post is based onexperiences with the SharePoint 2010 Technical Preview version.

    In the good old days of SharePoint 2003 and 2007 it was possible to save a site as a template. These sites were saved as .stp files, I assume this acronym stands for SiteTemPlate, a non-documented closed format that did not allow for modification in the saved template files. so new sites could be created based on the template. SharePoint 2010 promises the possibility to save a site as a WSP package, the Windows SharePoint Services Package format that we all love in the development of our SharePoint solutions, because it promises seamless deployments through the farm.

    In this series of blog posts I will investigate the power of this new functionality, and take you, the reader, along the way in trying to answer the following questions that directly pop up into my mind:

    • Is the site really exported as a WSP? And how does it look like at the inside?
    • If we create a new site based on the template, do changes to content types at the site collection level propagate to the content types in the new instance of the site template?
    • In Moss2007 it was not possible to export a publishing site as a site template. Well, actually you could, but it was not supported. Probably because pages and content a site publishing site depends on, like master pages, pages layouts, the style library and site collection images are managed at the site collection level (in the root site of the site collection). Did this change in 2010, and how is it handled?
    • What is exported. The complete configuration of the site, or only changes to the site with respect to the initial site definition?
    • Can we learn some new stuff on authoring WSP’s from the generated WSP’s?
    • Visual Studio SharePoint Support has a project type “Import SharePoint Solution Package”, what does that do? Can we use the WSP generated by a saved site template?

    Ok, let get started. The first steps to execute are:

    • Create a site based on the blank site definition
    • Export the site

    To showcase some of the new tools in the mean time I will use SharePoint Designer to create our new site:

    1. Connect to the portal, and select the Subsites tab
      image
    2. Create a new site named wspexport based on the Blank Site template
      image
    3. This brings us a blank site:
      image
      To inspect some of the export functionality we create a custom list MyList with a Title and Description field, and a document library MyDocuments. We put some entries in the custom list and add a document to the document library. I assume that everyone knowing something about SharePoint knows how to do this.

      Adding a simple Dummy.txt document to the document library:
      image

      The home page after adding list view web parts for the MyDocuments and MyList:
      image 
    4. We go back to SharePoint Designer, set the site Title and Description of the site and save as template
      image
    5. Selecting Save as template brings you to the web site where you can specify the template site settings
      image 

      When save as template is done we get to the following screen:
      image
    6. Following the user solution gallery will bring us to the Solution Gallery. This is a location where solutions can be uploaded and downloaded. These solutions can probably be solutions that can include code that will be run in a sandbox. More on this in an upcomming blog post.
      image
    7. Right-click on the WspExportSite and select Save Target As… to save the WSP file to your location of choice.
    8. Note that the saved solution can be activated by selecting the arrow next to its name
      image

    This concludes the first post in this series. What do we have:

    • A WSP file on disk based on Blank Site containing a list and a document library
    • A solution in our solution gallery ready to be activated

    Disclaimer: All information in this blog post is based on my personal interpretation of information collected at the SharePoint Conference 2009 and experiences with SharePoint 2010 Technical Preview version provided to my company in the PEP program.

  • SharePoint 2010: Getting Publishing template working

    Note: this post is only relevant for people running the SharePoint 2010 Technology Preview.

    When I create a new site based on the Publishing Portal template you get a .../Pages/Default.aspx page with an error on it. The error seems to be generated by a ContentByQuery web part (the only web part) on the page. Add ?contents=1 to the url (…/Pages/Default.aspx?contents=1):

    image

    Check Out the page, remove the web part (Delete, not Close), and your page starts working again.

    Happy Publishing!

    image

    Disclaimer: All information in this blog post is based on my personal interpretation of information collected at the SharePoint Conference 2009 and experiences with SharePoint 2010 Technical Preview version provided to my company in the PEP program.

  • SharePoint 2010: When SQL memory usage keeps growing…

    After a single machine SharePoint 2010 install using the built in SQL Server Express my machine became really sloooooooow. After checking the processes it became clear that SQL server was eating memory. This is the default behavior of SQL Server.

    I tried to install the SQL Server 2008 Manager Express, but the installation failed. The SQL Server Express provided with SharePoint 2010 seems to be a newer version than the SQL Server 2008 Express version.

    After a long search on the internet I finally found how to set the memory limits for a SQL Server instance through osql.exe.

    First thing to do is to determine which instance you want to limit. One way of doing this is by finding the process ID using the built in Task Manager, and then use the Sysinternals Process Explorer to determining what instance is running under that process ID. On my machine .\SHAREPOINT was good enough for connecting to the SQL Server instance used by SharePoint.

    1. Launch a command prompt
    2. Start the SQL prompt, connecting to the desired instance (e.g. .\SHAREPOINT)
    3. osql -E -S SERVERNAME\<INSTANCENAME>
    4. Execute the following commands to enable setting of advance options:

      USE master
      EXEC sp_configure 'show advanced options',1
      RECONFIGURE WITH OVERRIDE
      GO
    5. Execute the following commands to set the maximum memory in MB. Replace 200 with your desired setting (I use 200MB):

      USE master
      EXEC sp_configure 'max server memory (MB)',200
      RECONFIGURE WITH OVERRIDE
      GO
    6. Execute the following commands to disable advanced settings, for safety’s sake:

      USE master
      EXEC sp_configure 'show advanced options',0
      RECONFIGURE WITH OVERRIDE
      GO
    7. quit

    Disclaimer: All information in this blog post is based on my personal interpretation of information collected at the SharePoint Conference 2009 and experiences with SharePoint 2010 Technical Preview version provided to my company in the PEP program.

  • SharePoint 2010: #SPC09 - Notes from the keynote

    Some quick notes I took about things I found interesting from the two keynote speeches of the SharePoint Conference 2009.

    Steve Ballmer keynote

    • SharePoint 2010 Beta release: November 2009
    • SharePoint 2010: RTM in First half 2010
    • Visual Studio Beta 2 released today!!
    • SharePoint Designer remains free in the 2010 version

    Versions of SharePoint:

    • SharePoint Foundation 2010  = WSS
    • SharePoint 2010 for Intranet Standard
    • SharePoint 2010 for Intranet Enterprise
    • SharePoint 2010 for Internet Standard
    • SharePoint 2010 for Internet Enterprise
    • SharePoint Online (for Intranet)
    • SharePoint Online for Internet facing sites (yes!)

    Jeff Taper keynote

    Code name Gemini becomes PowerPivot: 100.000.000 rows in Excel, publish to the server, powered by Analysis Services 2008 R2 (its FAST!!)

    Product names for PowerPivot:

    • Sql Server PowerPivot for Excel
    • Sql Server PowerPivot for SharePoint

    Disclaimer: All information in this blog post is based on my personal interpretation of information collected at the SharePoint Conference 2009 and experiences with SharePoint 2010 Technical Preview version provided to my company in the PEP program.

     

    .

  • Visual Studio: alway run as administrator

    I’m currently developing on a 64 bit Windows Server 2008 R2 that is domain joined, so I log in with my domain account and user access control is enabled. I need to run my Visual Studio as an administrator, because otherwise I get all kind of errors. I can do this by right-clicking on the Visual Studio Icon and select “Run as administrator”:

    image

    The problem is: I forget to do this all the time, and I ALWAYS want to run Visual Studio as an administrator.

    You can enable this as follows:

    1. Right-click the Visual Studio icon and select properties
    2. On the Shortcut tab (the default tab) select Advanced
      image
    3. Select Run as administrator
      image 
    4. Click OK

    This will work on any program, and on any OS with user access control (Vista, Windows 7, …).

    In order to be able to do this you must be added to the Administrators group on the local machine. If you don’t have the permissions to do this, login with an account that has enough permissions, or login with the local administrator account.

    You can do this in the Edit local users and groups program (Start –> Search programs and files… type users):

    image

    When you start up Visual Studio you will always get a warning from User Access Control with the question if you want to allow the program to make changes to your computer. Don’t know if you can prevent this popup.

  • SharePoint, Features and web.config modifications using SPWebConfigModification

    SharePoint has a great way for deploying content and functionality using Windows SharePoint Services Solution Packages (WSP's). While developing a powerful new feature for SharePoint Publishing sites I had to deploy a HttpModule "the SharePoint" way. Building a HttpModule , a corresponding feature and the resulting WSP package is easy with our Macaw Solutions Factory. The actual logic in the Http Module and the feature is the difficult part. One of the things I had to do was to create a feature that registers a HTTPModule on feature activation, and removes it from the web.config on the feature deactivation. You can do this using the SPWebConfigModification class.

    A good article on this topic is http://www.crsw.com/mark/Lists/Posts/Post.aspx?ID=32. It contains links to other posts as well.

    The Microsoft documentation can be found at SPWebConfigModification Class (Microsoft.SharePoint.Administration), I wished I scrolled down before, because a lot of valuable information can be found in the Community Content of this page (keep scrolling!).

    Anyway, it took quite some time to get my HttpModule to register/unregister correctly on activation/deactivation of my web application level feature. I post the code below so you have a head-start if you have to do something similar yourself.

     

    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    

    // namespace must be in the form <Company>.<Product>.<FunctionalArea>.SharePoint.Features.<FeatureName>.FeatureReceiver namespace Macaw.WcmRia.Moss2007.DualLayout.SharePoint.Features.DualLayoutSupport.FeatureReceiver { /// <summary> /// Add HttpModule registration to web.config of the web application /// </summary> class DualLayoutSupportFeatureReceiver : SPFeatureReceiver { private const string WebConfigModificationOwner = "Macaw.WcmRia.Moss2007.DualLayout"; private static readonly SPWebConfigModification[] Modifications = { // For not so obvious reasons web.config modifications inside collections // are added based on the value of the key attribute in alphabetic order. // Because we need to add the DualLayout module after the // PublishingHttpModule, we prefix the name with 'Q-'. new SPWebConfigModification() { // The owner of the web.config modification, useful for removing a // group of modifications Owner = WebConfigModificationOwner, // Make sure that the name is a unique XPath selector for the element // we are adding. This name is used for removing the element Name = "add[@name='Q-Macaw.WcmRia.Moss2007.DualLayout']", // We are going to add a new XML node to web.config Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, // The XPath to the location of the parent node in web.config Path = "configuration/system.web/httpModules", // Sequence is important if there are multiple equal nodes that // can't be identified with an XPath expression Sequence = 0, // The XML to insert as child node, make sure that used names match the Name selector Value = "<add name='Q-Macaw.WcmRia.Moss2007.DualLayout' type='Macaw.WcmRia.Moss2007.DualLayout.Business.Components.HttpModule, Macaw.WcmRia.Moss2007.DualLayout.Business.Components, Version=1.0.0.0, Culture=neutral, PublicKeyToken=077f92bbf864a536' />" } };

        <span style="color: blue">public override void </span>FeatureInstalled(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties)
        {
        }
    
        <span style="color: blue">public override void </span>FeatureUninstalling(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties)
        {
        }
    
        <span style="color: blue">public override void </span>FeatureActivated(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties)
        {
            <span style="color: #2b91af">SPWebApplication </span>webApp = properties.Feature.Parent <span style="color: blue">as </span><span style="color: #2b91af">SPWebApplication</span>;
            <span style="color: blue">if </span>(webApp != <span style="color: blue">null</span>)
            {
                AddWebConfigModifications(webApp, Modifications);
            }
        }
    
        <span style="color: blue">public override void </span>FeatureDeactivating(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties)
        {
            <span style="color: #2b91af">SPWebApplication </span>webApp = properties.Feature.Parent <span style="color: blue">as </span><span style="color: #2b91af">SPWebApplication</span>;
            <span style="color: blue">if </span>(webApp != <span style="color: blue">null</span>)
            {
                RemoveWebConfigModificationsByOwner(webApp, WebConfigModificationOwner);
            }
        }
    
        <span style="color: gray">/// &lt;summary&gt;
        /// </span><span style="color: green">Add a collection of web modifications to the web application
        </span><span style="color: gray">/// &lt;/summary&gt;
        /// &lt;param name=&quot;webApp&quot;&gt;</span><span style="color: green">The web application to add the modifications to</span><span style="color: gray">&lt;/param&gt;
        /// &lt;param name=&quot;modifications&quot;&gt;</span><span style="color: green">The collection of modifications</span><span style="color: gray">&lt;/param&gt;
        </span><span style="color: blue">private void </span>AddWebConfigModifications(<span style="color: #2b91af">SPWebApplication </span>webApp, <span style="color: #2b91af">IEnumerable</span>&lt;<span style="color: #2b91af">SPWebConfigModification</span>&gt; modifications)
        {
            <span style="color: blue">foreach </span>(<span style="color: #2b91af">SPWebConfigModification </span>modification <span style="color: blue">in </span>modifications)
            {
                webApp.WebConfigModifications.Add(modification);
            }
    
            <span style="color: green">// Commit modification additions to the specified web application
            </span>webApp.Update();
            <span style="color: green">// Push modifications through the farm
            </span>webApp.WebService.ApplyWebConfigModifications();
        }
    
        <span style="color: gray">/// &lt;summary&gt;
        /// </span><span style="color: green">Remove modifications from the web application
        </span><span style="color: gray">/// &lt;/summary&gt;
        /// &lt;param name=&quot;webApp&quot;&gt;</span><span style="color: green">The web application to remove the modifications from</span><span style="color: gray">&lt;/param&gt;
        /// &lt;param name=&quot;owner&quot;Remove all modifications that belong to the owner&gt;&lt;/param&gt;
        </span><span style="color: blue">private void </span>RemoveWebConfigModificationsByOwner(<span style="color: #2b91af">SPWebApplication </span>webApp, <span style="color: blue">string </span>owner)
        {
            <span style="color: #2b91af">Collection</span>&lt;<span style="color: #2b91af">SPWebConfigModification</span>&gt; modificationCollection = webApp.WebConfigModifications;
            <span style="color: #2b91af">Collection</span>&lt;<span style="color: #2b91af">SPWebConfigModification</span>&gt; removeCollection = <span style="color: blue">new </span><span style="color: #2b91af">Collection</span>&lt;<span style="color: #2b91af">SPWebConfigModification</span>&gt;();
    
            <span style="color: blue">int </span>count = modificationCollection.Count;
            <span style="color: blue">for </span>(<span style="color: blue">int </span>i = 0; i &lt; count; i++)
            {
                <span style="color: #2b91af">SPWebConfigModification </span>modification = modificationCollection[i];
                <span style="color: blue">if </span>(modification.Owner == owner)
                {
                    <span style="color: green">// collect modifications to delete
                    </span>removeCollection.Add(modification);
                }
            }
    
            <span style="color: green">// now delete the modifications from the web application
            </span><span style="color: blue">if </span>(removeCollection.Count &gt; 0)
            {
                <span style="color: blue">foreach </span>(<span style="color: #2b91af">SPWebConfigModification </span>modificationItem <span style="color: blue">in </span>removeCollection)
                {
                    webApp.WebConfigModifications.Remove(modificationItem);
                }
    
                <span style="color: green">// Commit modification removals to the specified web application
                </span>webApp.Update();
                <span style="color: green">// Push modifications through the farm
                </span>webApp.WebService.ApplyWebConfigModifications();
            }
        }
    }
    

    }

  • SharePoint WCM: flushing publishing pages from the cache

    SharePoint WCM does a lot of caching. One of the things that is cached are the publishing pages. These pages are cached in the object cache. Sometimes there is a situation where you want to flush a publishing page from the cache. In my case I had to flush a publishing page from the cache in a http module. The cache id for this page is the server relative url without any characters after the url. For example: /Pages/MyFirstLittleWCMPage.aspx. Therefore the path must be "normalized" so additional "stuff" is removed. The NormalizeUrl() function does this job.

    What I want to do to flush the page from the cache was:

    CacheManager contextCacheManager = CacheManager.GetManager(SPContext.Current.Site);
    contextCacheManager.ObjectFactory.FlushItem(NormalizeUrl(HttpContext.Current.Request.Path);

    Sadly enough many interesting and powerful API classes are internal, and you need some reflection to be able to call them. Below the code I needed to write to accomplish the above. I can tell you it was a hell of a job to get to this code. That is why I share it, to give you some insight in the required magic called reflection.

    Interesting components:

    1. I know that the assembly containing the required class is already loaded. I can do GetAssembly(typeof(PublishingPage)) to get the assembly. Will work on any class in the assembly.
    2. To invoke a member of a class you need the type of the class. Assembly.GetType("full.name.of.type") returns the type, also on internal classes.
    3. Given the type you can invoke members, where members can be static functions, properties or methods. You specify what to search for the member using BindingFlags. For example for a static public method specify BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod.
    4. Arguments to methods must be passed in an object array.

    I hope the code below will give some insight in how to make the impossible possible.

    /// <summary>
    /// Flush the current publishing page from the object cache
    /// </summary>
    /// <remarks>
    /// Reflection is used to get access to internal classes of the SharePoint framework
    /// </remarks>
    private void FlushCurrentPublishingPageFromCache()
    {
        // We need to get access to the Microsoft.SharePoint.Publishing.dll assembly, PublisingPage is in there for sure
        Assembly microsoftSharePointPublishingAssembly = Assembly.GetAssembly(typeof(PublishingPage));
        Type cacheManagerType = microsoftSharePointPublishingAssembly.GetType("Microsoft.SharePoint.Publishing.CacheManager", true);
        object contextCacheManager = cacheManagerType.InvokeMember("GetManager", 
            BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, 
            null, null, new object[] { SPContext.Current.Site });            
    
    <span style="color: blue">string </span>cacheId = NormalizeUrl(<span style="color: #2b91af">HttpContext</span>.Current.Request.Path);
    <span style="color: blue">if </span>(contextCacheManager != <span style="color: blue">null</span>)
    {
        <span style="color: blue">object </span>cachedObjectFactory = contextCacheManager.GetType().InvokeMember(<span style="color: #a31515">&quot;ObjectFactory&quot;</span>, 
            <span style="color: #2b91af">BindingFlags</span>.Instance | <span style="color: #2b91af">BindingFlags</span>.Public | <span style="color: #2b91af">BindingFlags</span>.GetProperty, 
            <span style="color: blue">null</span>, contextCacheManager, <span style="color: blue">new object</span>[] {});
        cachedObjectFactory.GetType().InvokeMember(<span style="color: #a31515">&quot;FlushItem&quot;</span>, <span style="color: #2b91af">BindingFlags</span>.Instance | 
            <span style="color: #2b91af">BindingFlags</span>.Public | <span style="color: #2b91af">BindingFlags</span>.InvokeMethod, 
            <span style="color: blue">null</span>, cachedObjectFactory, <span style="color: blue">new object</span>[] { cacheId });
    }
    <span style="color: blue">else
    </span>{
        Microsoft.Office.Server.Diagnostics.<span style="color: #2b91af">PortalLog</span>.LogString(<span style="color: #a31515">&quot;Unexpected error: DualLayout &quot; +<br />           &quot;FlushCurrentPublishingPageFromCache: No CacheManager for page {0}&quot;</span>, cacheId);
    }
    

    }

    /// <summary> /// Normalize url for cachId usage /// </summary> /// <remarks> /// This code is copied from: /// private static string NormalizeUrl(string url); /// Declaring Type: Microsoft.SharePoint.Publishing.CachedObjectFactory /// Assembly: Microsoft.SharePoint.Publishing, Version=12.0.0.0 /// </remarks> /// <param name="url">Url to normalize</param> /// <returns>The normalized url</returns> private static string NormalizeUrl(string url) { url = SPHttpUtility.UrlPathDecode(url, false); if (!string.IsNullOrEmpty(url)) { int length = url.IndexOf('?'); if (length >= 0) { url = url.Substring(0, length); } } else { return ""; } int index = url.IndexOf('#'); if (index >= 0) { url = url.Substring(0, index); } return url; }

  • Debugging SharePoint/ASP.NET code? Smart key-codes + disable timeout!

    I'm currently running around in the Visual Studio debugger to debug some complex SharePoint code. There are two things really annoy me: all the mouse-clicks needed to attach to the Internet Information Server process and the time-out you get when you are exploring complex data-structures for too long.

    First my favorite key-sequence for the last week: <ALT-D>PW3<ENTER><ENTER>. I will explain it:

    <Alt-D> brings up the debugging menu in Visual Studio:

    image

    With P the action "Attach to Process..." is executed, which brings you to the following window:

    image

    The list of available processes is already active. We nog need to select the Internet Information Server worker process. Each application pool has it's own worker process. These worker processes are named: w3wp.exe.

    By typing W3 the first (and often only) w3wp.exe process is selected:

    image 

    If there are multiple w3wp.exe processes you could select them all (SHIFT+ARROWDOWN). Now press the first time <ENTER>, which selects the w3wp.exe process(es). This results in the following window:

    image

    The "Attach" button is selected by default. This brings us to the latest <ENTER> to accept the default selection.

    We are now attached to the correct Internet Information Server working process(es) and can start debugging.

    Just try it a few times: <ALT-D>PW3<ENTER><ENTER>, it will become second nature in no time. Happy debugging....

    ... until you get the following popup window:

    image 

    You have got a "ping" timeout. If you read the box well, it tells you exactly what happened, and it tells you to press the "Help" button for further details.

    Most people don't read the box, and start over again. But it worth the effort to follow the described steps from the Microsoft documentation, they are a bit hard to follow:

    To continue to debug, you must configure IIS to allow the worker process to continue.

    To enable Terminal Services (?? Terminal Services ??)
    1. Open the Administrative Tools window.

    2. Click Start, and then choose Control Panel.

    3. In Control Panel, choose Switch to Classic View, if necessary, and then double-click Administrative Tools.

    4. In the Administrative Tools window, double-click Internet Information Services (IIS) Manager.

    5. In the Internet Information Services (IIS) Manager window, expand the <computer name> node.

    6. Under the <computer name> node, right-click Application Pools.

    7. In the Application Pools list, right-click the name of the pool your application runs in, and then click Advanced Settings.

    8. In the Advanced Settings dialog box, locate the Process Model section and choose one of the following actions:

      1. Set Ping Enabled to False.

        -or-

      2. Set Ping Maximum Response Time to a value greater than 90 seconds.

      Setting Ping Enabled to False stops IIS from checking whether the worker process is still running and keeps the worker process alive until you stop your debugged process. Setting Ping Maximum Response Time to a large value allows IIS to continue monitoring the worker process.

    9. Click OK.

    10. Under Services and Applications, click Services. -- Don't know what the rest of the steps if for... you are done!

      A list of services appears in the right-side pane.

    11. In the Services list, right-click Terminal Services, and then click Properties.

    12. In the Terminal Services Properties window, locate the General tab and set Startup type to Manual.

    13. Click OK to close the Advanced Settings dialog box.

    14. Close the Internet Information Services (IIS) Manager window and the Administrative Tools window.

    I'm running on Windows Server 2008, and below are the steps that I follow:

    Just type iis in the Start Search box, this shows me two applications:

    image

    I take the top one (I'm not running under IIS 6) and get the following screen:

    image

    Right-click your application pool, advanced settings... and you get the following screen:

    image

    Set "Ping Enabled" to False, press OK, and you can drill through your data-structures in the debugger for as long as you want!

    Again: "Happy debugging!"

  • SPDevExplorer 2.3 – Edit SharePoint content from within Visual Studio (4)

    After a weekend of hard work I have a new version of SPDevExplorer ready with many new enhancements. Download at http://spdevexplorer.codeplex.com/WorkItem/View.aspx?WorkItemId=7799

    See http://weblogs.asp.net/soever/archive/tags/SPDevExplorer/default.aspx for all myposts on SPDevExplorer.

  • Some screen shots to give an impression:

    Connect to a SharePoint site:

    image

    Checkout and edit a page from SharePoint:

    image

    Actions on the context menu of a site:

    image

    Actions on the context menu of a folder:

    image

    Actions on the context menu of a file:

    image

    Add files from working folder to SharePoint:

    image

    Version 2.2:
    - Added consistent keyboard shortcuts for all context menu entries
    - Changed "Published by VS 2005" and Checked in by VS 2005" to "Published by SPDevExplorer" and Checked in by SPDevExplorer"
      because add-in works with both VS 2005 and VS 2008.
    - All file content communication between working folder and sharepoint is now binary. Was text before, with
      conversion to UTF8. This allows for uploading modified binary files and editing in Visual Studio
      of non-text files.
    - Extended file information on files retrieved from SharePoint with last time modified for improving
      test on overwrite of modified files.
    - Added "Save" to file menu. If a file is opened in Visual Studio, it is saved and the contents is saved
      to SharePoint. If it is not opened in Visual Studio, if it is saved from another application to
      the working folder, the file is saved to SharePoint. Now images and other files can be opened from
      the working folder and saved back to SharePoint.
    - Refactoring and documentation of code (first steps)
    - Added "Add file..." option on folder that allows you to add files that are in the working folder, but
      are not in SharePoint. This makes it possible to create files with any application in the working folder
      and add them to SharePoint using Visual Studio.
    - Added "Explorer working folder..." to all folders, not only to site. Makes it easier to add new files.
    - Changed menu action on site "SharePoint->Settings" to "SharePoint->Site Settings
    - Added "SharePoint->Open site in browser", "SharePoint->Open folder in browser", "SharePoint->Open file in browser"
      to open the site, folder or file in a browser window within Visual Studio
    - Added "SharePoint->Web part page maintenance" on files, this opens the file url with ?contents=1 appended in a
      browser window in Visual Studio. A special page is displayed where web parts can be deleted. Useful for pages that
      don't work anymore due to a not working web part
    - Added method "CurrentWebServiceVersion" to the SPDevExplorer web service so we can make sure that the client side tool
      and the server side web service stay in sync

    Version 2.1:
    - Fixed a bug where subnodes where not rendered when enabling/disabling "Show all folders and files"
    - When loading a site, the site node now directly expands
    - Refresh on site gave "Not implemented", it now works
    - Removed SharePoint Settings and SharePoint COntents options on folders. Gave a "Not implemented"
      message, and I don't see a use for them
    - Add New/File, New/Folder, Get/Files, Get/Files recursive also to the Site node, to be able to do this
      on the root of the site as well
    - Changed Checkin to Check In, and Checkout to Check Out to be consistent with SharePoint Designer
    - Disable Publish if publishing not enabled on library
    - Show Publish only if file is Checked In
    - If Checked Out, show Check In with the user that has file currently checked out
    - Added Rename on files and folders to folder and file context menu
    - Added consistent short cuts for all context menu entries
    - WSP install.bat script: added -force on deploysolution so it can be executed if solution already installed
    - Removed Site & System, folder with log files and contente types. Do content types through WebUI, use other tool for log files
    - Fixed "Check Out" visualization of files in root of site

    Version 2.0:
    - Converted the project into a Visual Studio 2008 project
    - Changed spelling error Domin into Domain
    - Generated a strong key for the SPDevExplorer.Solution project. I got an error when installing the WSP rthat assembly was not strong-signed.
    - Cookies were retrieved on an empty cookies object, this lead to a object not found exception
    - Several changes to make sure that https is supported by changing the UI that full path is shown in tree.
      You now see
    https://mysite instead of just mysite.
    - Added "Explore working folder..." on site, so the cache on the local file system can be found. Want to turn
      this into a feature to add files to the cache folders and be able to add these additional files.
    - Added "Show info..." on files and folders, shows the cached xml info on the folder/file
    - On delete file/folder, ask for confirmation
    - On delete file/folder, refresh parent view to make sure it is correct again, make next node current, if not exist previous node
    - Made keyboard interaction working, KeyPress was used, didn't work, now using KeyUp
    - Del on keyboard now works correctly for deleting files/directories
    - F5 on keyboard added for refresh. Parent folder is refreshed if on File, current folder is refreshed if on folder
    - Removed (Beta) from name in window title
    - Moved "SharePoint Explorer" from "View" menu to "Tools" menu, more appropriate place
    - Option on site "Show all folders and files". Normally there is a list of hidden folders, but this also hides files you migh
      want to edit like files in the forms folders of lists
    - Removed adding list of webs to a site, gave an error and sites were never added. All sites must be added explicitly
      using "connect...". I think it is also better this way.

    Note that the download version is named version 2.3, but internally this is version 2.2. I messed up with the numbering.

  • SPDevExplorer 2.1 – edit SharePoint content from within Visual studio (3)

    I did a lot of additional bugfixing and enhancements on SPDevExplorer. Resulted in version 2.1 of SPDevExplorer. Download bin + sources at http://spdevexplorer.codeplex.com/WorkItem/View.aspx?WorkItemId=7799. Let me know if you find any issues.

    See http://weblogs.asp.net/soever/archive/tags/SPDevExplorer/default.aspx for all myposts on SPDevExplorer.

     

    Modifications by Serge van den Oever [Macaw]:
    ============================================

    Version 2.1:
    - Fixed a bug where subnodes were not rendered when enabling/disabling "Show all folders and files"
    - When loading a site, the site node now directly expands
    - Refresh on site gave "Not implemented", it now works
    - Removed SharePoint Settings and SharePoint COntents options on folders. Gave a "Not implemented"
      message, and I don't see a use for them
    - Add New/File, New/Folder, Get/Files, Get/Files recursive also to the Site node, to be able to do this
      on the root of the site as well
    - Changed Checkin to Check In, and Checkout to Check Out to be consistent with SharePoint Designer
    - Disable Publish if publishing not enabled on library
    - Show Publish only if file is Checked In
    - If Checked Out, show Check In with the user that has file currently checked out
    - Added Rename on files and folders to folder and file context menu
    - Added consistent short cuts for all context menu entries
    - WSP install.bat script: added -force on deploysolution so it can be executed if solution already installed
    - Removed Site & System, folder with log files and contente types. Do content types through WebUI, use other tool for log files
    - Fixed "Check Out" visualization of files in root of site

    Version 2.0:
    - Converted the project into a Visual Studio 2008 project
    - Changed spelling error Domin into Domain
    - Generated a strong key for the SPDevExplorer.Solution project. I got an error when installing the WSP rthat assembly was not strong-signed.
    - Cookies were retrieved on an empty cookies object, this lead to a object not found exception
    - Several changes to make sure that https is supported by changing the UI that full path is shown in tree.
      You now see
    https://mysite instead of just mysite.
    - Added "Explore working folder..." on site, so the cache on the local file system can be found. Want to turn
      this into a feature to add files to the cache folders and be able to add these additional files.
    - Added "Show info..." on files and folders, shows the cached xml info on the folder/file
    - On delete file/folder, ask for confirmation
    - On delete file/folder, refresh parent view to make sure it is correct again, make next node current, if not exist previous node
    - Made keyboard interaction working, KeyPress was used, didn't work, now using KeyUp
    - Del on keyboard now works correctly for deleting files/directories
    - F5 on keyboard added for refresh. Parent folder is refreshed if on File, current folder is refreshed if on folder
    - Removed (Beta) from name in window title
    - Moved "SharePoint Explorer" from "View" menu to "Tools" menu, more appropriate place
    - Option on site "Show all folders and files". Normally there is a list of hidden folders, but this also hides files you migh
      want to edit like files in the forms folders of lists
    - Removed adding list of webs to a site, gave an error and sites were never added. All sites must be added explicitly
      using "connect...". I think it is also better this way.

  • SPDevExplorer – edit SharePoint content from within Visual studio (1)

    There is a great project http://SPDevExplorer.codeplex.com by TheKid that allows you to edit SharePoint content from within Visual studio. This is especially handy when creating SharePoint Publishing sites where you are editing master pages and page layouts. Most people do this in SharePoint designer, hating the fact that SharePoint Designer messes with your code and sometimes locks files mysteriously. SPDevExplorer allows you to do this using Visual Studio using the great Visual Studio editor.

    See http://weblogs.asp.net/soever/archive/tags/SPDevExplorer/default.aspx for all myposts on SPDevExplorer.

    The release on codeplex is a bit old and had some issues so I decided to dive into the code and solve some issues. I published my first updated version as an Issue on the project, because that allowed me to add attachments. See http://spdevexplorer.codeplex.com/WorkItem/View.aspx?WorkItemId=7799 for the updated version. Both binaries and source code included.

    The biggest changes I made:

    • Https is now supported
    • It is now possible to see and edit all files

    I solved the following issues:

    • Converted the project into a Visual Studio 2008 project
    • Changed spelling error Domin into Domain, make some other texts consistant
    • Generated a strong key for the SPDevExplorer.Solution project. I got an error when installing the WSP rthat assembly was not strong-signed.
    • Cookies were retrieved on an empty cookies object, this lead to a object not found exception
    • Several changes to make sure that https is supported by changing the UI that full path is shown in tree
    • You now see https://mysite instead of just mysite.
    • Added "Explore working folder..." on site, so the cache on the local file system can be found. Want to turn this into a feature to add files to the cache folders and be able to add these additional files.
    • Added "Show info..." on files and folders, shows the cached xml info on the folder/file
    • On delete file/folder, ask for confirmation
    • On delete file/folder, refresh parent view to make sure it is correct again, make next node current, if not exist previous node
    • Made keyboard interaction working, KeyPress was used, didn't work, now using KeyUp
    • Del on keyboard now works correctly for deleting files/directories
    • F5 on keyboard added for refresh. Parent folder is refreshed if on File, current folder is refreshed if on folder
    • Removed (Beta) from name in window title
    • Moved "SharePoint Explorer" from "View" menu to "Tools" menu, more appropriate place
    • Option on site "Show all folders and files". Normally there is a list of hidden folders, but this also hides files you might want to edit like files in the forms folders of lists
    • Removed adding list of webs to a site, gave an error and sites were never added. All sites must be added explicitly using "connect...". I think it is also better this way.

    In a next post I will show some of the features of this great tool (video).

    Note that it is not possible edit the web parts in web part pages with this tool (web parts are not part of the page), and that it is not possible to edit pages in the Pages document library, the actual content is managed in the meta data of the connected content type.

  • Macaw Vision on SharePoint Release Management

    Developing SharePoint solutions is fun, especially with our Macaw Solutions Factory because we have all the tools to go from development to test to acceptation and to production. But then you want to make a modification to your version 1.0 SharePoint solution. How do you do that? We know how... with our Site Management Tool which is part of the Macaw solutions factory! Read all about our vision and concepts in the blogpost by my collegue Vincent hoogendoorn. Read Macaw Vision on SharePoint Release Management and let us know what you think of it.

    Posts available so far on the Macaw Solutions Factory:

    And if you are interested, tracks us on:

  • Factory Overview, Part 1: A Bird’s Eye View of the Macaw Solutions Factory

    A very interesting and extensive overview of our Macaw Solutions Factory has just been published by my collegue Vincent hoogendoorn. It is our first installment in our "Macaw Solutions Factory Overview" blogpost series: Factory Overview, Part 1: A Bird’s Eye View of the Macaw Solutions Factory. This blog post touches on all the work I have been doing in the last years. Check it out, I think it is impressive, and it gives a real look into the kitchen on how our company and our customers are doing software projects. We will continue with a lot more posts, for example on how we do end-to-end SharePoint development with the Macaw Solutions Factory.

    The post also describes one of the tools I open-sourced lately: the CruiseControl.NET Build Station. This is a "local build server" running in a Windows Forms application that you can use on your local machine to do builds of your current code tree, and on the code tree as available in source control.

    CruiseControl.Net Build Station 

    Posts available so far on the Macaw Solutions Factory:

    And if you are interested, tracks us on:

  • Factory Vision, Part 1: Introducing the Macaw Solutions Factory

    We finally started our public "comming out" on a project we are working on for few years already: the Macaw Solutions Factory.

    Vincent just posted the first installment in our "Macaw Solutions Factory Vision" blogpost series: Factory Vision, Part 1: Introducing the Macaw Solutions Factory.

    We are very interested in your feedback.

    Posts available so far on the Macaw Solutions Factory:

    And if you are interested, tracks us on:

  • Help: Windows LiveWriter not working anymore against http://weblogs.asp.net?

    I almost stopped blogging because Windows Livewriter stopped working against my http://weblogs.asp.net account on three different platforms.

    I get the following error when trying to post with LiveWriter:

    The response to the metaWeblog.newPost method received from the weblog server was invalid:

    Invalid response document returned from XmlRpc server

    or when I am logged in on the administration part of the web site and try to post using LiveWriter:

    An unexpected error has occurred while attempting to log in:

    Invalid Server Response - The response to the blogger.getUsersBlogs method received from the weblog server was invalid:

    Invalid response document returned from XmlRpc server

    Do others experience problems as well? Does anyone know a solution?

    Regards, Serge

  • PowerShell: Return values from a function through reference parameters

    PowerShell has a special [ref] keyword to specify which parameters are used in a fuction to return values. It's usage is not directly clear however.

    If the type of the variable to update is a value type, use the [ref] keyword in the declaration of the function parameter, this specifies that a "pointer" to the variable will be passed.

    To pass the "pointer" to the variable, use ([ref]$variable) to create the pointer, and pass this as parameter. To set the value of the value variable pointed to by the "pointer", use the .Value field.

    Simple example to show what [ref] does:

    C:\Program Files\PowerGUI> $zz = "hoi"
    C:\Program Files\PowerGUI> $xz = [ref]$zz
    C:\Program Files\PowerGUI> $xz
    Value
    -----
    hoi

    C:\Program Files\PowerGUI> $xz.Value = "dag"
    C:\Program Files\PowerGUI> $zz
    dag 

    This is only required for value types, not is the type is a referece type like for example Hashtable.

    Some sample code:

    function fn
    {
    param
    (
    [ref]$arg1,
    [ref]$arg2,
    $arg3
    )

    $arg1.Value = 1
    $arg2.Value = "overwrite"
    $arg3.key = "overwrite hash value"
    }

    $x = 0
    $y = "original"
    $z = @{"key" = "original hashvalue"}
    $x
    $y
    $z.key
    fn -arg1 ([ref]$x) -arg2 ([ref]$y) -arg3 $z
    $x
    $y
    $z.key

  • Presentation on the Business Productivity Online Suite as given at DIWUG

    Yesterday evening I gave a presentation on the Business Productivity Online Suite (BPOS) for the DIWUG. The session was hosted by Sparked in Amsterdam.

    I uploaded the presentation at my skydrive.

    The presentation starts with a general introduction to BPOS. It then zooms in on the features of SharePoint Online and gives some ideas on how you could integrate Silverlight applications with BPOS.

    Part of the presentation is in Dutch, but I think most of the presentation can be understood by English readers as well because most computer related terms are in English.

    Interesting links when starting developing for BPOS:

    EU regulations:

  • Documenting PowerShell script code

    The Macaw Solutions Factory contains a lot of PowerShell script code. A lot of the code is documented, but it is not documented in a consistent way because there were no documentation standards available for PowerShell 1.0, we only had the very complex XML based MAML documentation standard that was not useable for inline documentation.

    With the (upcoming) introduction of PowerShell 2.0, a new more readable documentation standard for PowerShell code is introduced. I did not find any formal documentation on it, only examples on the PowerShell team blog. There is even a script to create a weblog post out of a script containing this documentation format. See http://blogs.msdn.com/powershell/archive/tags/Write-CommandBlogPost/default.aspx for this script and an example of the documentation format.

    The new documentation format uses a PowerShell 2.0 feature for multi-line comments:

    <#
    :
    \#>

    Because this is not supported in PowerShell 1.0 , we will write the documentation as follows to remain compatible:

    \#<#
    \#:
    \##>

    This will allows us to change the documentation by removing the superfluous # characters when the code-base is moved over to PowerShell 2.0 when it is released.

    Documenting PowerShell scripts

    Scripts can be provided with documentation in the following format:

    #<#
    #.Synopsis
    #	Short description of the purpose of this script
    #.Description
    #	Extensive description of the script
    #.Parameter X
    #    Description or parameter X
    #.Parameter Y
    #    Description or parameter Y
    #.Example
    #	First example of usage of the script
    #.Example
    #	Second example of usage of the script
    ##>
    param
    (
    	X,
    	Y
    )
    :
    

    function MyFunction { #<# #.Synopsis # Short description of the purpose of this function #.Description # Extensive description of the function #.Parameter X # Description or parameter X #.Parameter Y # Description or parameter Y #.Example # First example of usage of the function #.Example # Second example of usage of the function ##> param ( X, Y ) : }

    :

    Automatically generating documentation

    The next step is to automatically generate documentation on all our scripts based on the new documentation format.

    The best approach will possibly be to use PowerShell 2.0 to actually generate the documentation, because using PowerShell 2.0 we can parse PowerShell code. We can easily determine the functions and their parameters.

    A nice project for the future.

  • Microsoft Tag, funny idea, will it take off?

    Microsoft came up with a simple but funny and possibly really effective idea: Microsoft Tag. You can create a nice visual tag consisting of colorful triangles, and when you scan this tag with the camera of your Internet enabled cell phone you get connected to a web page, vcard, a text note or a dialar (audio) advertisement. I just tried it out, I created a tag to this web log:

    1. I logged in into http://www.microsoft.com/tag with my live ID account
    2. Created a new tag to my weblog:
      image
    3. This results in my first tag on my personal tags site:
      image
    4. I rendered the tag to a PDF by clicking on the Tag icon:
      image
    5. I downloaded the Tag Reader application for my iPhone from the AppStire (the link http://gettag.mobi just says that, it provides no download link)
    6. I snapped a photo from the on screen PDF file, allowing the iPhone to access my location information (smart),  and..... nothing. I got an error.
    7. I was a bit disappointed so i fired up the introductory movie on http://www.microsoft.com/tag, snapped a really bad photo from a tag in this movie and guess what! It worked! It brought me to a Vista advertisement.

    I think the idea is good. This can be used very well for print on posters, advertisement, the price and information cards next to a TV in a shop etc. etc. The introductory movie gives some good examples like an advertisement for a concert with a Tag that brings you to the booking page, or at a bus station where the Tag brings you to an online schedule of the bus. Wondering if this will take of.

    On the site you can get a report on snaps of your Tags:

    image

    And hey, I got three hits!! So the Tag was recognized, just the linking failed!

    The Tag picture above should point to my weblog, maybe it will start working in a while. Try it all out, and I will let you know about the results in a later blog post.

    It would be really interesting if the report would also use the location information that can be provided by the Tag Reader application (the iPhone version does if you allow this), so you know where your Tag was snapped.

    Time to print a T-Shirt with my personal Tag...

  • Inspecting SharePoint

    When developing for SharePoint you absolutely need a SharePoint inspection tool, a tool that can navigate through the SharePoint object model and SharePoint content.

    A nice tool is http://www.codeplex.com/spi that comes with source code, but it has a few issues:

    • The latest release 1.0.0.0 is old
    • A newer version is available, but you must compile it yourself from the code respository (I included a compiled version on the codeplex site at http://www.codeplex.com/spi/WorkItem/View.aspx?WorkItemId=8785)
    • It only shows a small subset of SharePoint information, for example you can't see content type definitions, fields, or SharePoint content

    Another great tools in Echo SharePoint Spy. It can be downloaded at http://www.echotechnology.com/products/spy. In their own words:

    "This powerful free tool will allow you to spy into the internal data of SharePoint and compare the effects of making a change. Sharepoint Spy also allows you to compare settings between sites, lists, views, etc helping you troubleshoot configurations."

    You need to register and will get an e-mail with download details and a registration key.

    When I tried to install the Echo SharePoint Spy tool on my Windows Server 2008 development server it refused. The installer is an MSI file, and after some googling I stumbled upon a weblog post on how to extract files from an MSI file using the MSIerables tool that can be found at Softpedia. After opening the MSI file you get the following view:

    image

    After extracting the SharePointSpy.exe file you can just run it on Windows Server 2008.

    The Echo SharePoint Spy tool has some cool features:

    image
    Show the field definitions of a list and their internal mapping to the database field

    image

    Show the schema of a view, right-click on right window (Internet Explorer window) and select View Source to see the actual xml in Notepad.

    You can compare any two object by right-clicking an object and select "Compare this object with...", then select a second object and select "... compare with this item".

     

    Check them out!